[转]PHP hook钩子类

来源:互联网 发布:mac怎么用ps 编辑:程序博客网 时间:2024/05/22 16:17

不多说什么,用于做插件,消息监听之类的东西,反正用处挺大的,不清楚的请移步看看百科知识。

  当然,代码之后只有使用的测试,而没有删除的测试,各种问题自行解决吧,还有功能不强,理论上应该可以设置优先级才对,但是这里不行,不完善的原因吧。

  基本原理还是很简单的,用列表存储对应的调用函数或方法,然后执行的时候调用并且返回一下就行了。还有钩子的作用是修改数据,所以必须传递一个参数过去,即使你用不到任何参数,发送个null参数过去也是可以的,并非没有意义,而是有时候部分数据很难直接调用,要使用全局变量或者通过其他方式获取的时候,空值也是不错的,至于返回对象,这个也必须的。

先贴类代码。

<?phpnamespace 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;

接着是运行结果输出数据。

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}
0 0
原创粉丝点击