thinkphp 5 阅读笔记——Hook

来源:互联网 发布:skype mac版 编辑:程序博客网 时间:2024/04/29 22:26
\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 来配置更方便。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 快递水果压坏了怎么办 谈对象被骗了钱怎么办 如果遇到半夜坏人敲门怎么办 小孩晚上不进房间睡觉怎么办 房子照不到阳光潮湿怎么办 4个月婴儿不拉屎怎么办 小孩六个月奶不够吃怎么办 到晚上就没奶水怎么办 20多天奶水不够怎么办 四个月奶不够吃怎么办 7个月宝宝不肯吃东西怎么办 6个月宝宝不肯吃东西怎么办 十一个月宝宝不肯吃东西怎么办 九个月宝宝不肯吃辅食怎么办 八个月宝宝不肯吃辅食怎么办 七个月宝宝不肯吃辅食怎么办 7个月宝不吃辅食怎么办 在月子里奶不够怎么办 8月宝宝不吃辅食怎么办 8个月不吃辅食怎么办 宝宝不吃药怎么办一岁 奶水不足宝宝又不吃奶粉怎么办 一岁婴儿突然不吃饭怎么办 一岁宝宝突然不吃饭怎么办 一岁半宝宝突然不爱吃饭怎么办 1岁宝宝突然不爱吃饭怎么办 一岁多宝宝突然不爱吃饭怎么办 一岁半宝宝突然不吃饭怎么办 八个月宝宝不吃奶粉怎么办 小孩铅超标怎么办如何排铅 宝宝突然不吃辅食怎么办 6个月宝宝不喝奶怎么办 宝宝4月不吃母乳怎么办 不吃母乳怎么办 8个月 宝宝不吃奶粉母乳又不够怎么办 宝宝只吃母乳不吃奶粉怎么办 十个月宝宝不爱吃辅食怎么办 奶水不足宝宝不吃奶粉怎么办 两个月宝宝不吃奶瓶怎么办 宝宝拉的有鼻涕怎么办 七个月宝宝拉肚子拉水怎么办