您好,欢迎来到筏尚旅游网。
搜索
您的当前位置:首页ThinkPHP3.2扩展

ThinkPHP3.2扩展

来源:筏尚旅游网

之前写到TP3.1的行为扩展是tag();在TP3.2中引入了另一种说法—:钩子。 我们来看一下TP3.2中的钩子这个东西: 一:文件流程: 1:/index.php - require './ThinkPHP/ThinkPHP.php'; 2:/ThinkPHP/ThinkPHP.php—- require CORE_PATH.'Think'.EXT; Think\Think:

之前写到TP3.1的行为扩展是tag();在TP3.2中引入了另一种说法—:钩子。
我们来看一下TP3.2中的钩子这个东西:
一:文件流程:
1:/index.php ->require './ThinkPHP/ThinkPHP.php';
2:/ThinkPHP/ThinkPHP.php—->require CORE_PATH.'Think'.EXT; Think\Think::start();
3:/ThinkPHP/Library/Think/Think.class.php—–>App::run();
4:/ThinkPHP/Library/Think/App.class.php 。到这里基本流程就走完了,(这里不说细节);

二:代码:
1:看一下 App::run()方法:

 
 Hook::listen('app_init');
 App::init();
 
 Hook::listen('app_begin');
 // Session初始化
 if(!IS_CLI){
 session(C('SESSION_OPTIONS'));
 }
 // 记录应用初始化时间
 G('initTime');
 App::exec();
 
 Hook::listen('app_end');
 return ;

其中的Hook::listen(”)就是用来执行钩子的,我们可以在app_init这个安插的位置用来获取应用中安装的插件。

看一下Hook::listen();

 @param @param mixed $params 传入参数
 * @return void
 */
 static public function listen($tag, &$params=NULL) {
 if(isset(self::$tags[$tag])) {
 if(APP_DEBUG) {
 G($tag.'Start');
 trace('[ '.$tag.' ] --START--','','INFO');
 }
 foreach (self::$tags[$tag] as $name) {
 APP_DEBUG && G($name.'_start');
 $result = self::exec($name, $tag,$params);
 if(APP_DEBUG){
 G($name.'_end');
 trace('Run '.$name.' [ RunTime:'.G($name.'_start',$name.'_end',6).'s ]','','INFO');
 }
 if(false === $result) {
 // 如果返回false 则中断插件执行
 return ;
 }
 }
 if(APP_DEBUG) { // 记录行为的执行日志
 trace('[ '.$tag.' ] --END-- [ RunTime:'.G($tag.'Start',$tag.'End',6).'s ]','','INFO');
 }
 }
 return;
 }

其中关键是:self::exec($name, $tag,$params); 看一下exec的代码:

 /**
 * 执行某个插件
 * @param string $name 插件名称
 * @param @param Mixed $params 传入的参数
 * @return void
 */
 static public function exec($name, $tag,&$params=NULL) {
 if(false === strpos($name,'\\')) {
 // 插件(多个入口)
 $class = "Addons\\{$name}\\{$name}Addon";
 }else{
 // 行为扩展(只有一个run入口方法)
 $class = $name.'Behavior';
 $tag = 'run';
 }
 $addon = new $class();
 return $addon->$tag($params);
 }

最后还不是 new $class();进而return $addon->$tag($params); 又转到了具体钩子的代码方法。其实就是我们原本的调用class的方法,只不过经过别人的高度封装了。

三:那么问题来了,这个钩子有什么用呢? 怎么用?
这里以OneThink 的{:hook('AdminIndex')}为例,看一些别人是怎么用的。
在系统初始化到 Hook::listen('app_init'); 时,

array('Common\Behavior\InitHook')
);

一看就明白,无非就是读取持久化的信息,放到缓存或是其他的方式

 // 行为扩展的执行入口必须是run
 public function run(&$content){
 if(isset($_GET['m']) && $_GET['m'] === 'Install') return;

 $data = S('hooks');
 if(!$data){
 $hooks = M('Hooks')->getField('name,addons');
 foreach ($hooks as $key => $value) {
 if($value){
 $map['status'] = 1;
 $names = explode(',',$value);
 $map['name'] = array('IN',$names);
 $data = M('Addons')->where($map)->getField('id,name');
 if($data){
 $addons = array_intersect($names, $data);
 Hook::add($key,$addons);
 }
 }
 }
 S('hooks',Hook::get());
 }else{
 Hook::import($data,false);
 }
 }

当在程序执行到{:hook(‘AdminIndex’)}时—>调用的是Hook::listen(‘AdminIndex’);
AdminIndex这个挂载点包含了三个插件:分别是:SiteStat, SystemInfo,DevTeam。
用一个循环来分别按顺序执行.

总结:钩子其实就是起到一个挂载点的作用,这个钩子挂在哪里,就可以在哪里执行,内容或功能就是挂载插件或类库的具体实现。这样实现的代码就有很大的灵活性,挂载点不变,挂的东西变量,功能也就相应的变化,是不是很灵活强大呀。


以上只属于学习笔记,若有错请指正。

Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务