第21课:PHP钩子hook实现

PHP钩子常常用于项目中的插件,一个项目主体功能很有限,经常会加上很多扩展功能,以插件的形式存在
而这些插件不可避免的和主体项目会有耦合关联,而钩子就是为了实现项目的模块化,让他们各自独立而用能相互作用
钩子顾名思义,就是在主体项目中放入很多钩子,主体项目某个操作之后,触发这些钩子执行,而这些钩子直接连接各个插件

其实,聪明的同学已经发现,钩子的实现其实就是设计模式中所说的观察者模式
下面用代码来说明,钩子是怎么实现的
<?php
class Hook {//我们来写一个通用的钩子类,在项目中,主要通过这个类来挂钩与执行

	private static $actions = array();//用这个数组来存贮钩子所能执行的所有功能方法

	/**
	 * 添加钩子
	 * @param $hook
	 * @param $function
	 */
	public static function addAction($hook, $function) {   
	    $hook = mb_strtolower($hook, CHARSET);
	    if(!self::exists_action($hook)) {
		self::$actions[$hook] = array();
	    }
	    if (is_callable($function)) {
		self::$actions[$hook][] = $function;
		return TRUE;
	    }
	    return FALSE ;
	}

	/**
	 * 运行钩子
	 * @param string $hook
	 * @param array $params
	 * @return boolean true if a hook was setted
	 */
	public static function doAction($hook, $params = NULL) {
	    $hook = mb_strtolower($hook, CHARSET);
	    if(isset(self::$actions[$hook])) {
		foreach(self::$actions[$hook] as $function) {
		    if (is_array($params)) {
			call_user_func_array($function, $params);//钩子方法可能需要传递参数,不是可能,是大部分情况下都需要
		    } else {
			call_user_func($function);
		    }
		}
		return TRUE;
	    }
	    return FALSE;
	}

	/**
	 * 获取钩子
	 * @param string $hook
	 * @return mixed
	 */
	public static function getAction($hook) {
	    $hook = mb_strtolower($hook, CHARSET);
	    return (isset(self::$actions[$hook]))? self::$actions[$hook] : FALSE;
	}

	/**
	 * 检查钩子的功能是否能实现
	 * @param string $hook
	 * @return boolean
	 */
	public static function existsAction($hook) {
	    $hook = mb_strtolower($hook, CHARSET);
	    return (isset(self::$actions[$hook])) ? TRUE : FALSE;
	}
}

调用方式:
//添加钩子
Hook::addAction('godeye','class::test');

//执行钩子
Hook::doAction('godeye');

打赏  如对你有帮助,请我喝杯咖啡吧!