不多说什么,用于做插件,消息监听之类的东西,反正用处挺大的,不清楚的请移步看看百科知识。
当然,代码之后只有使用的测试,而没有删除的测试,各种问题自行解决吧,还有功能不强,理论上应该可以设置优先级才对,但是这里不行,不完善的原因吧。
基本原理还是很简单的,用列表存储对应的调用函数或方法,然后执行的时候调用并且返回一下就行了。还有钩子的作用是修改数据,所以必须传递一个参数过去,即使你用不到任何参数,发送个null参数过去也是可以的,并非没有意义,而是有时候部分数据很难直接调用,要使用全局变量或者通过其他方式获取的时候,空值也是不错的,至于返回对象,这个也必须的。
先贴类代码。
<?php
namespace Core;
/**
* 系统钩子
* @author loveyu
*/
class Hook{
/**
* 用于存放对应的构造列表
* @var array
*/
private $_hook_list;
/**
* 构造方法
*/
public function __construct(){
// TODO: Implement __construct() method.
$this->_hook_list = array();
}
/**
* 添加一个钩子到系统
* @param string $name
* @param callback $func
*/
public function add($name, $func){
if(!isset($this->_hook_list[$name])){
$this->_hook_list[$name] = array();
}
if(is_array($func)){
$this->_hook_list[$name][get_class($func[0]) . ":" . $func[1]] = $func;
} else{
$this->_hook_list[$name][$func] = $func;
}
}
/**
* 应用钩子,至少包含一个参数名
* @param string $name 对应名称
* @param mixed $param1 第一个参数
* @return mixed 返回调用的第一个参数
*/
public function apply($name, $param1){
if(isset($this->_hook_list[$name])){
$args = array_slice(func_get_args(), 1);
foreach($this->_hook_list[$name] as $v){
$param1 = call_user_func_array($v, $args);
$args[0] = $param1;
}
}
return $param1;
}
/**
* 移除对应的钩子
* @param string $name 钩子名称
* @param callback|string $func 钩子对应的调用方法
*/
public function remove($name, $func = ''){
if(isset($this->_hook_list[$name])){
if(empty($func)){
unset($this->_hook_list[$name]);
} else{
if(is_array($func)){
if(isset($this->_hook_list[$name][get_class($func[0]) . ":" . $func[1]]))
unset($this->_hook_list[$name][get_class($func[0]) . ":" . $func[1]]);
} else{
if(isset($this->_hook_list[$name][$func]))
unset($this->_hook_list[$name][$func]);
}
}
}
}
}
namespace Core;
/**
* 系统钩子
* @author loveyu
*/
class Hook{
/**
* 用于存放对应的构造列表
* @var array
*/
private $_hook_list;
/**
* 构造方法
*/
public function __construct(){
// TODO: Implement __construct() method.
$this->_hook_list = array();
}
/**
* 添加一个钩子到系统
* @param string $name
* @param callback $func
*/
public function add($name, $func){
if(!isset($this->_hook_list[$name])){
$this->_hook_list[$name] = array();
}
if(is_array($func)){
$this->_hook_list[$name][get_class($func[0]) . ":" . $func[1]] = $func;
} else{
$this->_hook_list[$name][$func] = $func;
}
}
/**
* 应用钩子,至少包含一个参数名
* @param string $name 对应名称
* @param mixed $param1 第一个参数
* @return mixed 返回调用的第一个参数
*/
public function apply($name, $param1){
if(isset($this->_hook_list[$name])){
$args = array_slice(func_get_args(), 1);
foreach($this->_hook_list[$name] as $v){
$param1 = call_user_func_array($v, $args);
$args[0] = $param1;
}
}
return $param1;
}
/**
* 移除对应的钩子
* @param string $name 钩子名称
* @param callback|string $func 钩子对应的调用方法
*/
public function remove($name, $func = ''){
if(isset($this->_hook_list[$name])){
if(empty($func)){
unset($this->_hook_list[$name]);
} else{
if(is_array($func)){
if(isset($this->_hook_list[$name][get_class($func[0]) . ":" . $func[1]]))
unset($this->_hook_list[$name][get_class($func[0]) . ":" . $func[1]]);
} else{
if(isset($this->_hook_list[$name][$func]))
unset($this->_hook_list[$name][$func]);
}
}
}
}
}
然后是测试代码。
<?php
/*
* 系统钩子测试文件
*/
require("../core/hook.php");
$hook = new \Core\Hook();
/**
* 回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
*/
function test_hook_callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
}
/**
* 测试类
*/
class test_hook_class{
/**
* 类方法回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
*/
public function callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
}
/**
* 静态方法回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
*/
public static function static_callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
}
}
//函数回调
$hook->add('test_hook', 'test_hook_callback');
//静态方法回调
$hook->add('test_hook', 'test_hook_class::static_callback');
//实例化类
$test_class = new test_hook_class();
//添加方法
$hook->add('test_hook', array($test_class, 'callback'));
//需要处理的数据
$data = "loveyu";
//执行回调函数,顺序为添加顺序,必须存在两个及以上参数
$data = $hook->apply('test_hook', $data, 1, 2);
//输出最终数据
echo "\n".$data;
/*
* 系统钩子测试文件
*/
require("../core/hook.php");
$hook = new \Core\Hook();
/**
* 回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
*/
function test_hook_callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
}
/**
* 测试类
*/
class test_hook_class{
/**
* 类方法回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
*/
public function callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
}
/**
* 静态方法回调函数
* @param $data 默认输入数据,必须
* @param $n1 附加数据,可选
* @param $n2 附加数据,可选
* @return string 返回数据,和$data类似
*/
public static function static_callback($data, $n1, $n2){
echo "Run at:" . __METHOD__ . "\n";
return $data . "\n{" . $n1 . "[" . __METHOD__ . "]" . $n2 . "}";
}
}
//函数回调
$hook->add('test_hook', 'test_hook_callback');
//静态方法回调
$hook->add('test_hook', 'test_hook_class::static_callback');
//实例化类
$test_class = new test_hook_class();
//添加方法
$hook->add('test_hook', array($test_class, 'callback'));
//需要处理的数据
$data = "loveyu";
//执行回调函数,顺序为添加顺序,必须存在两个及以上参数
$data = $hook->apply('test_hook', $data, 1, 2);
//输出最终数据
echo "\n".$data;
接着是运行结果输出数据。
Run at:test_hook_callback
Run at:test_hook_class::static_callback
Run at:test_hook_class::callback
loveyu
{1[test_hook_callback]2}
{1[test_hook_class::static_callback]2}
{1[test_hook_class::callback]2}
Run at:test_hook_class::static_callback
Run at:test_hook_class::callback
loveyu
{1[test_hook_callback]2}
{1[test_hook_class::static_callback]2}
{1[test_hook_class::callback]2}
不是很懂,不知道是什么意思。
多学习,自然而然就懂了
不懂啊 :chuichaui:
或许是我解释的不怎么清楚。看看其他介绍就会明白些
看我表情测试
:bingdong: :bye: :cahan: :chanmei: :chuichaui: :du: :fafengtuq: :feiwen: :gaoxing: :girl_qianshui: :girl_xianmu: :hanfeng: :huangdong: :imdead: :jujiong: :kaice: :leiben: :leilui: :leiyunle: :no: :pale: :qianshui_boy: :qiaoluo: :tiaosheng: :tu: :wohehe: :wusheng: :xiangxiang: :xianmu: :xingfu: :xinxi: :yibianqu: :yongbao: :yun: :zhes: :zhesssss:
太高深 ,看懂
好吧,这个确实有点
虽然不懂,不过还是来看看。。。太高级了。
或许注释多了点。不过还是挺简单的用法
不明觉厉,点32个赞~
好吧,赞一个就行了
又是一位PHP大神呐
这也算大神??
跳大神的也算啊……
好吧!