1.行为扩展和插件机制
行为扩展实际上就是在执行程序的流程里埋下一个钩子,你可以往钩子里添加你自己的业务逻辑,当程序执行到某个钩子位置时将自动触发你的业务逻辑。
一.行为
2.注册钩子
(1)tags.php,路径:Application/Common/Conf/tag.php
<?php
return array(
'login'=>array('Common\Behavior\InitHook')
);
?>
其对应的文件是Application/Common/Behaviors/InitHook
(2)动态添加,假如这个钩子只在Public控制器中使用,那么可以在PublicController的_initialize()初始化方法中动态添加钩子
function _initialize() {
\Think\Hook::add('login', 'Common\Behavior\InitHook');
}
3.监听,触发钩子
function login() {
\Think\Hook::listen('login', run的参数);
}
当执行login方法时,会触发login行为,执行行为类的run方法
4.run方法
Common\Behavior\InitHook文件
class InitHookBehavior {
public function run(param) {
//要执行的代码
}
}
综上:先注册钩子,监听钩子,之后会触发run方法
二.插件
1.注册
tags.php
<?php
return array('showflash'=>array('test'));
?>
注册行为需要包含命名空间,当没有命名空间只有一个单词的时候将认为是一个插件
插件定义在Application/Addons/插件名/插件名Addon.class.php
比如上面的test插件就是Application/Addons/test/testAddon.class.php
插件类的定义
<?php
namespace Addons\test
class testAddon{
function showflash(){
echo "插件执行入口";
}
}
?>
这里有个明显的区别,就是run入口变成了showflash和钩子名相同
在加入一个插件
'clearflash'=>array('test');
<?php
namespace Addons\test
class testAddon{
function showflash(){
echo “这是showflash插件”;
}
function clearflash(){
echo "这是clearflash插件";
}
}
三.tp实现原理
1.add方法
添加插件到某个标签
/* tag 标签名称,name 插件名称*/
static public function add($tag, $name) {
//如果没有这是标签名,则定义成数组
if (!isset(self::$tags[$tag])) {
self::$tags[$tag] = array();
}
//如果该插件名称是数组,则合并数组,否则追加数组
if (is_array($name)) {
self::$tags[$tag] = array_merge(self::$tags[$tag], $name);
} else {
self::$tags[$tag][] = $name;
}
}
2.listen监听标签的插件
static public function listen($tag, &$params=NULL) {
if (isset(self::$tags[$tag])) {
foreach(self::$tags[$tag] as $name) {
$result = self::exec($name, $tag, $params);
if (false === $result) return;//如果返回false则直接中断插件执行
}
}
}
3.执行某个插件
加载插件,并且执行插件的$tag方法
static public function exec($name, $tag, &$params=NULL) {
if(false===strpos($name, '\\')) {
//插件
$class = "Addons\\{$name}\\{$name}Addon";
} else {
//行为扩展
$class = $name.'Behavior';
$tag = 'run';
}
$addon = new $class();
return $addon->$tag($params);
}