thinkphp(php)插件鉤子(hooks)分析的簡單實(shí)現(xiàn)機(jī)制
現(xiàn)在主流的cms或者blog等系統(tǒng)中,都內(nèi)置的有插件系統(tǒng),但是層層深入、剖析實(shí)現(xiàn)的方式,其實(shí)都是最簡單的鉤子的復(fù)雜化的實(shí)現(xiàn)。
前言
鉤子是插件執(zhí)行的觸發(fā)器;插件就像掛在鉤子上的東西;插件只有實(shí)現(xiàn)相應(yīng)鉤子方法,并安裝啟用成功后才能執(zhí)行。
開發(fā)者也可以用hook('test')方法在控制器只加入鉤子,讓你的應(yīng)用具有更好的擴(kuò)展性;同時(shí)也可以模板里加入鉤子{:hook('footer')};鉤子也支持傳入?yún)?shù)hook('footer',array('test'=>1));
向系統(tǒng)暴露你的鉤子,就是把你的鉤子在相應(yīng)的文件里列出來,系統(tǒng)會來檢測。
{:hooks('documentDetailAfter')}
這個(gè)的意思就是:相當(dāng)于在這邊 打一個(gè)點(diǎn) ,我們可以將插件掛載到那
官方的說法是:文檔末尾顯示顯示的 鉤子
意思就是說,在文檔末尾的時(shí)候,會自動調(diào)用掛載在那個(gè) 鉤子 上的插件
舉例說明
php中所謂的鉤子,其實(shí)就是一種事件驅(qū)動,主要分為‘注冊事件’、‘觸發(fā)事件’兩步。所謂‘注冊事件’,即目的是給未來可能發(fā)生的'事情'起一個(gè)名字,名字,可以用單例模式或者注冊 為一個(gè)全局的變量,用的時(shí)候直接在對應(yīng)的方法或者類再或者函數(shù)中插入這個(gè)變量即可;‘觸發(fā)事件’,本質(zhì)上就是在事件的全局變量中查詢要觸發(fā)的時(shí)間名稱,然后找到注冊號的類與方法,實(shí)例化運(yùn)行。
舉個(gè)例子來說明一下。
項(xiàng)目經(jīng)理給我們了如下的需求:
第一天:開發(fā)注冊的功能。
程序員巴拉巴拉,三下五除二就完成了。
第二天:在注冊前添加發(fā)送短信驗(yàn)證碼的功能。
程序員巴拉巴拉,三峽五除二就又完成了。
第三天:注冊完成之后,給用戶添加相應(yīng)的積分。
程序員又開始巴拉巴拉ing……
class Register{
public function index(){
/**
* 第二天發(fā)送短信功能
*/
/**
* 第一天注冊代碼
*/
/**
* 第三天增加積分功能
*/
}
}這樣一個(gè)人開發(fā)還好,多個(gè)人開發(fā),勢必會造成配合麻煩的問題,同時(shí)代碼也會變得混亂。
作為優(yōu)秀程序員的我們,當(dāng)然不容許我們程序中代碼冗余、混亂的出現(xiàn),于是我們把方法寫成函數(shù)獨(dú)立出來,方便調(diào)用與代碼簡介。于是形成如下代碼:
class Register{
public function index(){
/**
* 第二天發(fā)送短信功能
*/
sendMsg($data);
/**
* 第一天注冊代碼
*/
/**
* 第三天增加積分功能
*/
sendIntegral($data);
}
}
/**
* 發(fā)送短信
* @param {[type]} $data [description]
* @return {[type]} [description]
*/
function sendMsg($data){
/*
balabala
*/
}
/**
* 贈送積分
* @param {[type]} $data [description]
* @return {[type]} [description]
*/
function sendIntegral($data){
/*
balabala
*/
}但是我們想要把程序開元出去讓更多的人參與,這種直接修改源碼碼的方式始終不是太好,這個(gè)時(shí)候,我們就可以使用鉤子的方式,在注冊成功前后注冊兩個(gè)鉤子,我們只需要把鉤子告訴開發(fā)人員就行了,這樣他們不用改變源碼碼就可以輕易的進(jìn)行拓展。
class Register{
public function index(){
//注冊前鉤子
Hook::run('registerBefore');
/**
* 注冊代碼
*/
//注冊后鉤子
Hook::run('registerAfter');
}
}鉤子的簡單實(shí)現(xiàn)代碼
目錄結(jié)構(gòu):../hook/Hook.php
鉤子核心類Hook.php:
<?php
namespace hook;
class Hook{
static protected $hook = [];
/**
* 插件注冊
* @param [type] $name [description]
* @param [type] $addons [description]
*/
static public function add($name,$addons){
self::$hook[$name] = $addons;
}
/**
* 插件執(zhí)行
* @param [type] $name [description]
* @return [type] [description]
*/
static public function run($name){
if(isset(self::$hook[$name])){
$method = (new self::$hook[$name]());
call_user_func([$method,$name]);
}
}
}簡單的插件demo:
<?php
namespace addons\demo;
class Demo{
public function registerBefore(){
echo 'registerBefore'.'</br>';
}
public function registerAfter(){
echo 'registerAfter'.'</br>';
}
}插件實(shí)現(xiàn)的地方,即上文的注冊的文件:
<?php
namespace index\controller;
use hook\Hook;
class Index{
public function index(){
Hook::run('registerBefore');
echo '注冊完成'.'</br>';
Hook::run('registerAfter');
}
}入口文件index.php
<?php
use index\controller\Index;
spl_autoload_register('autoload');
function autoload($name){
require_once('/'.str_replace('\\','/',$name).'.php');
}
//插件注冊
hook\Hook::add('registerBefore','\\addons\\demo\\Demo');
hook\Hook::add('registerAfter','\\addons\\demo\\Demo');
//調(diào)用
$index = new Index();
$index->index();運(yùn)行接口如下:
- registerBefore
- 注冊完成
- registerAfter
如果要添加新的功能,程序員只要修改demo的插件就可,如果要拓展新的功能,只需要拓展registerBefore和registerAfter即可。
總結(jié)
可以說,鉤子就是掛載點(diǎn)。
掛載點(diǎn):在系統(tǒng)中提供給你一個(gè)掛載點(diǎn),我們可以進(jìn)行插件開發(fā),開發(fā)完成后,我們將其掛載到 掛載點(diǎn)上,會自動調(diào)用執(zhí)行。
到此這篇關(guān)于thinkphp(php)插件鉤子(hooks)分析的簡單實(shí)現(xiàn)機(jī)制的文章就介紹到這了,更多相關(guān)php插件鉤子(hooks)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP實(shí)現(xiàn)將瀏覽歷史頁面網(wǎng)址保存到cookie的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)將瀏覽歷史頁面網(wǎng)址保存到cookie的方法,涉及php對cookie的讀取、字符串轉(zhuǎn)化及保存等技巧,需要的朋友可以參考下2015-01-01
php 函數(shù)中靜態(tài)變量使用的問題實(shí)例分析
這篇文章主要介紹了php 函數(shù)中靜態(tài)變量使用的問題,結(jié)合實(shí)例形式分析了php 函數(shù)中靜態(tài)變量使用過程中遇到的問題,以及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2020-03-03
PHP中l(wèi)ist()函數(shù)用法實(shí)例簡析
這篇文章主要介紹了PHP中l(wèi)ist()函數(shù)用法,結(jié)合實(shí)例形式簡單分析了list()函數(shù)的功能,參數(shù)定義,使用技巧及相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-01-01
php switch語句多個(gè)值匹配同一代碼塊應(yīng)用示例
switch 語句一行接一行地執(zhí)行(實(shí)際上是語句接語句)。開始時(shí)沒有代碼被執(zhí)行,下面有個(gè)示例,需要的朋友可以參考下2014-07-07
PHP運(yùn)行出現(xiàn)Notice : Use of undefined constant 的完美解決方案分享
今天修改公司的網(wǎng)站,提示Notice : Use of undefined constant ,通過下面的方法解決了,最好是error_reporting(0);不需要更改配置2012-03-03
安裝ImageMagick出現(xiàn)error while loading shared libraries的解決方法
這篇文章主要介紹了安裝ImageMagick出現(xiàn)error while loading shared libraries的解決方法,是ImageMagick安裝與運(yùn)行中經(jīng)常出現(xiàn)的問題,需要的朋友可以參考下2014-09-09

