网站建设

phpcms v9 hook扩展

发表时间:2013-04-30 19:59:40 编辑:admin

什么是hook?直接翻译过来,就是钩子。这是一个术语也没什么。

钩子有什么好处呢?举个例子:

当我们先开发出一个会员模块,然后会员模块里面有一个删除会员的功能。我们在删除会员之前埋下一个钩子。这个叫钩子的埋点。如下代码:

<?php
$userid = intval($_GET['userid']);//接收要删除的会员ID
$this->db->delete(array('userid'=>$userid));//删除会员
hook::get_instance('member_delete_user')->run($userid);//埋下一个钩子传入被删除的会员ID
?>

后来由于需要,我们开发了一个文章系统,文章系统跟会员是关联的,所以删除会员也要把会员的文章一起删掉
在删除会员的时候我们就可以把这个member_delete_user钩子启用,再删除完会员之后把会员的文章也删掉。这样就不用修改到会员模块的代码。phpcms v9里面也有这个hook 但是官方没有怎么使用。而且也有局限。

现在我们来对phpcms v9的hook.class.php进行修改。代码如下:

<?php
/**
 *  hook.class.php 钩子类
 *
 * @copyright			(C) 2013 蝉印网络
 * @license				http://www.chanyinkeji.com
 * @lastmodify			2013-4-30
 * @qq					183517940
 */
class hook {
	private static $_instance = array();
	protected $hooks = array();
	
	private function __construct($hookkey) {
		$modules = getcache('modules','commons');
		if(is_array($modules) && !empty($modules)){
			foreach($modules as $k=>$v){
				//查找每个模块下hooks目录里面config.php文件是否存在
				$path = PC_PATH.'modules'.DIRECTORY_SEPARATOR.$v['module'].DIRECTORY_SEPARATOR.'hooks'.DIRECTORY_SEPARATOR;
				$file = $path.'config.php';
				if(is_file($file)){
					include_once $file;
				}
			}
			if(isset($hook[$hookkey]) && is_array($hook[$hookkey])){
				foreach($hook[$hookkey] as $k=>$v){
					$this->hooks[] = $v;
				}
			}
		}
	}
	/**
	 * 获取钩子实例对象
	 *
	 * @param string $hookkey 钩子名
	 * @return Hook
	 */
	public static function get_instance($hookkey) {
		if (!isset(self::$_instance[$hookkey])) {
			self::$_instance[$hookkey] = new self($hookkey);
		}
		return self::$_instance[$hookkey];
	}
	
	//运行钩子,传入参数
	public function run() {
		if (!$this->hooks) return;
		$args = func_get_args();
		foreach ($this->hooks as $key => $v){
			if(is_file($v['filename']) && $v['class'] && $v['function']){
				include_once $v['filename'];
				$class = new $v['class'];
				call_user_func_array(array($class,$v['function']), $args);
			}
		}
	}
}
?>

phpcms v9 hook使用方法:

在任意模块下(模块必须安装过才生效)新建一个hooks的文件夹,比如:phpcms/modules/content/hooks/
在目录里新建config.php,在里面写入如下代码:

//$hook['钩子名']
$hook['pre_controller'][] = array(
	'class'    => 'myclass',//类名
	'function' => 'init',//方法名称
	'filename' => PC_PATH.'modules'.DIRECTORY_SEPARATOR.'模块目录名'.DIRECTORY_SEPARATOR.'hooks'.DIRECTORY_SEPARATOR.'myclass.class.php',//注意模块目录名和类名
);

当 php执行到

hook:get_instance('pre_controller')->run();

时就会运行phpcms/modules/模块目录/hooks/myclass.class.php代码