當前位置:
首頁 > 知識 > WordPress解析系列之PHP編寫hook鉤子原理簡單實例

WordPress解析系列之PHP編寫hook鉤子原理簡單實例

WordPress作為全球應用最廣泛的個人博客建站工具,有很多的技術架構值得我們學習推敲。其中,最著名最經典的編碼技術架構就是採用了hook的機制。

hook翻譯成中文是鉤子的意思,單獨看這個詞我們難以理解這個hook機制(即鉤子機制)是什麼意思。那麼筆者就用大白話以通俗易懂方式給大家講解一下什麼是hook機制,以及用原生PHP函數編寫實現簡單實例。

大白話解釋:以Wordpress為例,它的hook機制就是在網頁載入時一起載入了很多hook變數,也就是鉤子變數,這些變數作用是綁定相關的函數,只要hook變數被載入,Wordpress就會用一個內置通用API函數解析出hook變數包含的函數並執行。好理解吧,一句話就說清楚了hook機制,但是實現並不簡單,最關鍵的就是那個內置API函數解析hook變數。後面筆者先不給大家掰Wordpress源碼的hook解析過程了,那個太複雜,考慮的方面很多,學習理解起來比較困難。這裡我們採用更簡單直接的解說方式,利用原生PHP函數編寫個簡單的hook機制plugin插件管理類,和大家一起更加直觀的理解鉤子機制的原理過程。

下面代碼的基本過程是:PluginManager內部有hook鍵值數組_listener。

1、plugin註冊到PluginManager類的包含hook鍵值的監聽數組_listener中,

2、PluginManager類實例對象調用trigger函數實現載入所有plugin插件並執行功能方法。

具體過程詳見如下代碼注釋分析:

<?php

// 已註冊插件管理核心類
class PluginManager
{
/**
* 監聽數組,保存所有已註冊插件的類私有的核心數組變數,數組的鍵名是鉤子名,值是對應的插件信息
* @var array private $_listeners
*/
private $_listeners = array;
/**
* 默認構造函數的作用是通過get_active_plugins讀取plugins目錄下所有已激活插件信息
* 同時初始化這些插件,註冊到核心類PluginManager數組變數$_listeners中
*
* @var array $plugins
* @return void
*/
public function __construct
{
//這裡$plugins數組包含我們獲取已激活的所有插件信息,通過get_active_plugins函數獲取具體信息
$plugins = array;
$plugins = $this->get_active_plugins;

if(is_array($plugins) && !empty($plugins) && count($plugins) > 0)
{
foreach($plugins as $plugin)
{
// 約定每個插件類的名字為如下格式,例如DemoActions;
$class = $plugin["name"]."Actions";
if(class_exists($class))
{
//初始實例化已激活插件,$this代表PluginManager實例為參數
new $class($this);
}
}
}
}

/**
* 註冊需要監聽插件的功能方法綁定到hook鉤子,並把hook鉤子加入到$_listeners數組
*
* @param string $hook 鉤子變數,就是數組的鍵名,每個鉤子可以綁定多個plugin插件類
* @param object $plugin 插件變數,get_class($plugin)獲取插件對應的類
* @param string $method 插件$plugin類對應的功能方法
*/
function register($hook, $plugin, $method)
{
//獲取插件實現的功能方法
$key = get_class($plugin)."->".$method;
//echo $key."<br>"; //這裡可以測試$key的值是否是實例方法引用;
//將插件的實例對象和功能方法保存入對應鍵值為hook名的監聽數組中
$this->_listeners[$hook][$key] = array($plugin, $method);
}

/**
* 返回已激活的所有插件名稱和路徑,讀取plugins目錄下所有已激活插件信息
*
* @return array $plugins 返回數組包含每組插件$name:插件名稱,也是php文件名;$directory:插件所在路徑
*/
function get_active_plugins
{
$dir = dirname(__FILE__).DIRECTORY_SEPARATOR."plugins";
$filesnames = scandir($dir);
$plugins = array;
foreach($filesnames as $filename)
{
if($filename!="." &&$filename!="..")
{
$plugins = array(
"name" => strstr($filename,".", true),
"directory"=>$dir);
}
}
return $plugins;
}

/**
* 觸發一個鉤子名稱下所有的插件自定義功能方法
*
* @param string $hook 鉤子的名稱
* @param mixed $data 輸入鉤子內對應插件自定義方法的參數,默認為空
* @return mixed
*/
function trigger($hook, $data="")
{
//查看要實現的鉤子,是否在監聽數組之中
if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0)
{
// 循環調用hook鉤子所有插件功能方法
foreach ($this->_listeners[$hook] as $listener)
{
// 取出插件實例對象類名
$class = $listener[0];
// 取出插件實例對象自定義的功能方法
$method = $listener[1];
if(method_exists($class,$method))
{
// 動態調用hook鉤子下所有插件的功能方法,這裡$data為可無的方法參數
$class->$method($data);
}
}
}
}

}

下面的是插件類DemoActions,其解析函數內包含對pluginManager對象的引用,對應的插件文件是Demo.php,該插件自定義功能方法為sayHello。

// 插件類,約定必須包含固定格式解析函數
class DemoActions
{
/**
* 解析函數的參數是pluginManager類的引用實例
* 函數調用pluginManager實例的register方法註冊這個插件
*/
function __construct(&$pluginManager)
{
/* hookdemo參數是鉤子的名稱
* $this是Demo_actions類的實例
* say_hello參數是此插件的功能方法
*/
$pluginManager->register("hookdemo", $this, "sayHello");
}

// 這裡是自定義的插件功能方法
function sayHello
{
echo "<br>Hello World<br>";
}
}

實際使用的時候,編輯如下代碼程序:

//實際應用程序
$pluginManager = new PluginManager; //插件管理類實例化對象
$pluginManager->trigger("hookdemo",""); //啟動綁定到hookdemo鉤子的所有插件功能;

至此,我們就完整的實現了hook鉤子綁定插件信息及如何利用hook鉤子執行插件自定義功能方法的原理。Wordpress的hook鉤子原理與此類似,理解了上面的代碼,再逐步深入理解Wordpress源碼的鉤子機制就會更加如魚得水。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

Restful介面調用方法超詳細總結
vue+mockjs 模擬數據,實現前後端分離開發
Handler實現線程之間的通信-下載文件動態更新進度條

TAG:達人科技 |

您可能感興趣

用 Python 編寫的 Python 解釋器
Marvel 計畫重新編寫《Fantastic Four》故事線
iPhone X 的新解鎖技術:用 Python 編寫 Face ID!
Spring Boot 基礎教程 ( 三 ) :使用 Cloud Studio 在線編寫、管理 Spring Boot 應用
如何在CUDA中為Transformer編寫一個PyTorch自定義層
如何編寫 bash completion script
如何開啟Gmail的Smart Compose並讓Google AI編寫您的郵件
Effective Python之編寫高質量Python代碼的59個有效方法
nodejs+mongodb 編寫 restful 風格博客 api
.gitignore詳解及編寫
基於Metasploit編寫終端檢測程序
用Click編寫Python命令行工具
Hegemon:使用 Rust 編寫的模塊化系統監視程序
使用 Cython 為 Python 編寫更快的 C 擴展
C++編寫Windows服務
不要在Python中編寫 lambda 表達式了
Servlet 編寫過濾器
用python編寫程序自動發表csdn博客
用彙編語言編寫TCP Bind Shell的菜鳥教程
shellcode快捷編寫工具,可針對多種常見系統指令編寫;POT:Twitter釣魚,全自動模仿給好友發釣魚鏈接