博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CI框架 -- 核心文件 之 Hooks.php
阅读量:7030 次
发布时间:2019-06-28

本文共 6727 字,大约阅读时间需要 22 分钟。

钩子 - 扩展框架核心

CodeIgniter 的钩子特性提供了一种方法来修改框架的内部运作流程,而无需修改 核心文件。CodeIgniter 的运行遵循着一个特定的流程,你可以参考这个页面的  。但是,有些时候你可能希望在 执行流程中的某些阶段添加一些动作,例如在控制器加载之前或之后执行一段脚本, 或者在其他的某些位置触发你的脚本。

 

启用钩子

钩子特性可以在 application/config/config.php 文件中全局的启用或禁用, 设置下面这个参数: $config['enable_hooks'] = TRUE;

 

挂钩点

CI框架可以实现在不修改系统核心文件的基础上来改变或增加系统的核心运行功能,那就是Hook,看看CI有哪些钩子:

    • pre_system
      系统执行的早期调用.仅仅在benchmark 和 hooks 类 加载完毕的时候. 没有执行路由或者其它的过程.
    • pre_controller
      在调用你的任何控制器之前调用.此时所用的基础类,路由选择和安全性检查都已完成.
    • post_controller_constructor
      在你的控制器实例化之后,任何方法调用之前调用.
    • post_controller
      在你的控制器完全运行之后调用.
    • display_override
      覆盖_display()函数, 用来在系统执行末尾向web浏览器发送最终页面.这允许你用自己的方法来显示.注意,你需要通过 $this->CI =& get_instance() 引用 CI 超级对象,然后这样的最终数据可以通过调用 $this->CI->output->get_output() 来获得。
    • cache_override
      可以让你调用自己的函数来取代output类中的_display_cache() 函数.这可以让你使用自己的缓存显示方法
    • post_system
      在最终着色页面发送到浏览器之后,浏览器接收完最终数据的系统执行末尾调用  

 

定义钩子

1 $hook['pre_controller'] = array(2                                 'class'    => 'TestHook', //调用的类名,如果你更喜欢使用过程式的函数的话,这一项可以留空。3                                 'function' => 'test', //调用的函数名4                                 'filename' => 'TestHook.php', //包含你的类或函数的文件名5                                 'filepath' => 'hooks', //包含你的脚本文件的目录名。 注意: 你的脚本必须放在 application/ 目录里面,所以 filepath 是相对 application/ 目录的路径,举例来说,如果你的脚本位于 application/hooks/ ,那么 filepath 可以简单的设置为 'hooks' ,如果你的脚本位于application/hooks/utilities/ , 那么 filepath 可以设置为 'hooks/utilities' ,路径后面不用加斜线6                                 'params'   => 'array()'//传递给脚本参数,可选7                                 );

 

多次调用同一个挂钩点

如果你想在同一个挂钩点处添加多个脚本,只需要将钩子数组变成二维数组即可,像这样:

$hook['pre_controller'][] = array(    'class'    => 'MyClass',    'function' => 'MyMethod',    'filename' => 'Myclass.php',    'filepath' => 'hooks',    'params'   => array('beer', 'wine', 'snacks'));$hook['pre_controller'][] = array(    'class'    => 'MyOtherClass',    'function' => 'MyOtherMethod',    'filename' => 'Myotherclass.php',    'filepath' => 'hooks',    'params'   => array('red', 'yellow', 'blue'));

注意数组索引后面多了个中括号:$hook['pre_controller'][]

这可以让你在同一个挂钩点处执行多个脚本,多个脚本执行顺序就是你定义数组的顺序。

 

钩子类分析

1 /**  2  * 钩子嘛,就是在不修改系统核心文件的基础上来改变或增加系统的核心运行功能  3  */  4 class CI_Hooks {  5    6     /**  7      * 检测hook是否开启  8      */  9     var $enabled        = FALSE; 10     /** 11      * config/hooks.php中的hooks配置信息 12      */ 13     var $hooks            = array(); 14     //防止死循环,因为钩子程序里面可能还还有钩子 15     var $in_progress    = FALSE; 16   17     //构造函数 18     function __construct() 19     { 20         $this->_initialize(); 21         log_message('debug', "Hooks Class Initialized"); 22     } 23   24     /** 25      * 初始化,获取hooks配合 26      */ 27     function _initialize() 28     { 29         $CFG =& load_class('Config', 'core'); 30   31         // 检测配置是否开启钩子 32         if ($CFG->item('enable_hooks') == FALSE) 33         { 34             return; 35         } 36   37         // 检测是否配置钩子 38         if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php')) 39         { 40             include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'); 41         } 42         elseif (is_file(APPPATH.'config/hooks.php')) 43         { 44             include(APPPATH.'config/hooks.php'); 45         } 46   47   48         if ( ! isset($hook) OR ! is_array($hook)) 49         { 50             return; 51         } 52   53         $this->hooks =& $hook; 54         $this->enabled = TRUE; 55     } 56   57     // -------------------------------------------------------------------- 58   59     /** 60      * 运行钩子程序,外部就是这样调用: 61          *     $EXT =& load_class('Hooks', 'core'); 62      *      $EXT->_call_hook('pre_system'); 63      */ 64     function _call_hook($which = '') 65     { 66         if ( ! $this->enabled OR ! isset($this->hooks[$which])) 67         { 68             return FALSE; 69         } 70                 //CI支持多次钩子,那么就是二维数组 71         if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0])) 72         { 73             foreach ($this->hooks[$which] as $val) 74             { 75                 $this->_run_hook($val); 76             } 77         } 78         else 79         { 80                         //一个钩子直接运行钩子 81             $this->_run_hook($this->hooks[$which]); 82         } 83   84         return TRUE; 85     } 86   87     // -------------------------------------------------------------------- 88   89     /** 90      * Run Hook 91      * 92      * Runs a particular hook 93      * 94      * @access    private 95      * @param    array    the hook details 96      * @return    bool 97      */ 98     function _run_hook($data) 99     {100         if ( ! is_array($data))101         {102             return FALSE;103         }104         105                 //防止死循环,因为钩子程序里面可能还还有钩子106         if ($this->in_progress == TRUE)107         {108             return;109         }110  111         //设置路径112                 //下面可以filepathfilepath就以那个文件夹(application)为基准,application/hooks下, 你可以把hooks 作为你的filepath113                 114         if ( ! isset($data['filepath']) OR ! isset($data['filename']))115         {116             return FALSE;117         }118  119         $filepath = APPPATH.$data['filepath'].'/'.$data['filename'];120  121         if ( ! file_exists($filepath))122         {123             return FALSE;124         }125  126         // -----------------------------------127         // Set class/function name128         // -----------------------------------129  130         $class        = FALSE;131         $function    = FALSE;132         $params        = '';133  134         if (isset($data['class']) AND $data['class'] != '')135         {136             $class = $data['class'];137         }138  139         if (isset($data['function']))140         {141             $function = $data['function'];142         }143  144         if (isset($data['params']))145         {146             $params = $data['params'];147         }148  149         if ($class === FALSE AND $function === FALSE)150         {151             return FALSE;152         }153  154         //不用多说了吧155         $this->in_progress = TRUE;156  157         //获取钩子配置信息成功后,运行钩子程序158         if ($class !== FALSE)159         {160             if ( ! class_exists($class))161             {162                 require($filepath);163             }164  165             $HOOK = new $class;166             $HOOK->$function($params);167         }168         else169         {170             if ( ! function_exists($function))171             {172                 require($filepath);173             }174  175             $function($params);176         }177                 // //执行相应程序完毕后,重新把当前hook的状态改为非运行中,以让它可以再次被触发。178         $this->in_progress = FALSE;179         return TRUE;180     }181  182 }

 

转载于:https://www.cnblogs.com/hf8051/p/5160283.html

你可能感兴趣的文章
Trie树实现
查看>>
Opencv无法调用cvCaptureFromCAM无法打开电脑自带摄像头
查看>>
Exception异常处理机制
查看>>
复杂的web---web中B/S网络架构
查看>>
编写文档的时候各种问题
查看>>
Eclipse里maven的project报Unbound classpath variable: 'M2_REPO/**/***/***.jar
查看>>
新旅程CSS 基础篇分享一
查看>>
查看内核函数调用的调试方法【原创】
查看>>
个人项目中遇到的问题
查看>>
byte与base64string的相互转化以及加密算法
查看>>
20145103 《Java程序设计》第3周学习总结
查看>>
ubuntu声音系统
查看>>
Java基础-关于session的详细解释
查看>>
洛谷P4364 IIIDX
查看>>
程序员恶搞图片===爆笑中......娱乐一下.....
查看>>
Debian 7.0.0 安装教程图解
查看>>
普通用户加sudo权限
查看>>
Linq 处理 List数据
查看>>
VISTA下的.NET2005 WEB应用程序
查看>>
WCF 第六章 序列化和编码 使用代理序列化类型
查看>>