PHP hook钩子类

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

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

  基本原理还是很简单的,用列表存储对应的调用函数或方法,然后执行的时候调用并且返回一下就行了。还有钩子的作用是修改数据,所以必须传递一个参数过去,即使你用不到任何参数,发送个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]);
                }
            }
        }
    }
}

然后是测试代码。

<?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}

15条评论在“PHP hook钩子类”

  1. 看我表情测试
    :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:

写下你最简单的想法