thinkphp 5 阅读笔记——Hook

\think\app::initCommon 流程分析
namespace think; //定义之后的类,属于 think命名空间下

use think\Hook; //use关键字目的是使用namespace的别名, 此处省略了as..., 相当于直接用最后的Hook,相当于 use think\Hook as Hook , 之后可以直接 使用 Hook 代替 think\Hook 。

//重新申请一块比较大的buffer
if (ob_get_level() > 0) {
$output = ob_get_clean(); // 得到当前缓冲区的内容并删除当前输出缓。
}
ob_start();

.... //注册 应用的命名空间 'app'->'E:\xs2016\tp5/application/ '
//加载额外文件 $config['extra_file_list'] ,如 helper.php。 在这之后 dump等函数才能开始使用

// 监听tags : app_init (\think\app::init 中 已加载行为扩展文件,application/tags.php)
Hook::listen('app_init'); //此处为行为标签位,标签名:app_init



\think\Hook::exec //类似于“切面” 给某一个切面绑定相关行为执行。利用call_user_func_array实现

public static function exec($class, $tag = '', &$params = null, $extra = null)
{ //$class (要执行的行为),$tag(方法名/标签名) 对应 application/tags.php中的设置。
App::$debug && Debug::remark('behavior_start', 'time');
if (is_callable($class)) { //如果是合法可执行函数,则直接调用
$result = call_user_func_array($class, [ & $params, $extra]);
$class = 'Closure';
} elseif (is_object($class)) {
//如果是对象,则调用对象的方法名
// 类与对象的关系就如模具和铸件的关系,类的实例化结果就是对象,而对一类对象的抽象就是类。
$result = call_user_func_array([$class, $tag], [ & $params, $extra]);
$class = get_class($class);
} else {
$obj = new $class(); //实例化对象,如果该对象存在$tag方法,则调用$tag方法。否则,调用该对象的run方法。你的行为类,可以只写run方法,也可以写$tag方法。 对应到tags.php中的配置, 要写全class的命名空间,以方便自动加载,因为这个行为类之前没有use namespace的别名 进来的,所以要用完整的命名空间。
$result = ($tag && is_callable([$obj, $tag])) ? $obj->$tag($params, $extra) : $obj->run($params, $extra);
}
if (App::$debug) {
Debug::remark('behavior_end', 'time');
Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info');
}
return $result;
}

从 exec 可以推导出 tags.php配置的写法,tags.php可以批量导入。 也可以单独用 Hook中的add,来进行 行为绑定

// 应用行为扩展定义文件 tags.php
return [
// 应用初始化
'app_init' => ['app\\index\\controller\\Index'], //这里用的完整命名空间 , app_init 为$tag
...
];

//路径 E:\xs2016\tp5\application\index\controller\Index.php
namespace app\index\controller;

class Index
{
public function index($name = 'World')
{... }
public function app_init(){
var_dump("应用初始化时,执行app_init()");
}
}
运行结果打印:


手动行为绑定,要注意位置,要在应用标签位listen之前。比如app_init的listen在app.php 的 init()。可以整站搜索 Hook::listen 可以看到内置的标签位。

// 加载基础文件
require __DIR__ . '/base.php';
\think\Hook::add('app_init','app\\index\\controller\\Index');
\think\Hook::add('app_begin','app\\index\\controller\\Index');
// 执行应用
App::run()->send();

用tags.php 来配置更方便。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值