CodeIgniter源代码阅读(五)Hooks.php

  1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2 /**
  3  * CodeIgniter
  4  *
  5  * An open source application development framework for PHP 5.1.6 or newer
  6  *
  7  * @package        CodeIgniter
  8  * @author        ExpressionEngine Dev Team
  9  * @copyright    Copyright (c) 2008 - 2011, EllisLab, Inc.
 10  * @license        http://codeigniter.com/user_guide/license.html
 11  * @link        http://codeigniter.com
 12  * @since        Version 1.0
 13  * @filesource
 14  */
 15 //根据配置(application/config/hooks.php)中的特定配置来调用函数
 16 // ------------------------------------------------------------------------
 17 
 18 
 19 //调用
 20 
 21 /**
 22  * CodeIgniter Hooks Class
 23  *
 24  * Provides a mechanism to extend the base system without hacking.
 25  *
 26  * @package        CodeIgniter
 27  * @subpackage    Libraries
 28  * @category    Libraries
 29  * @author        ExpressionEngine Dev Team
 30  * @link        http://codeigniter.com/user_guide/libraries/encryption.html
 31  */
 32 class CI_Hooks {
 33 
 34     /**
 35      * Determines wether hooks are enabled
 36      *
 37      * @var bool
 38      */
 39     var $enabled        = FALSE;//开启hook的标志,默认是关闭的。APPPATH/config/config.php中的配置也是默认关闭的,如果想使用hook,要在config.php中开启。
 40     /**
 41      * List of all hooks set in config/hooks.php
 42      *
 43      * @var array
 44      */
 45     var $hooks            = array();////在_initialize()函数初始化的过程中将APPPATH/config/hook.php中定义的hook数组,引用到$this->hooks;
 46     /**
 47      * Determines wether hook is in progress, used to prevent infinte loops
 48      *
 49      * @var bool
 50      */
 51     var $in_progress    = FALSE;//当一个hook执行的时候,会给标记 $in_process = TRUE ,是为了防止同一个hook被同时调用。
 52 
 53     /**
 54      * Constructor
 55      *
 56      */
 57     function __construct()
 58     {
 59         $this->_initialize();
 60         log_message('debug', "Hooks Class Initialized");
 61     }
 62 
 63     // --------------------------------------------------------------------
 64 
 65     /**
 66      * Initialize the Hooks Preferences
 67      *
 68      * @access    private
 69      * @return    void
 70      */
 71     //初始化hook 
 72     function _initialize()
 73     {
 74         $CFG =& load_class('Config', 'core');//获取配置文件
 75         // If hooks are not enabled in the config file
 76         // there is nothing else to do
 77         //如果配置文件中设置了是不允许hooks,则直接返回退出本函数。
 78         if ($CFG->item('enable_hooks') == FALSE)////判断config.php中是否开启hook
 79         {
 80             return;
 81         }
 82 
 83         // Grab the "hooks" definition file.
 84         // If there are no hooks, we're done.
 85 //要使用到的钩子,必须在配置目录下的hooks.php里面定义好。否则无法使用。
 86         if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
 87         {
 88             include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
 89         }
 90         elseif (is_file(APPPATH.'config/hooks.php'))
 91         {
 92             include(APPPATH.'config/hooks.php');
 93         }
 94 
 95 
 96         if ( ! isset($hook) OR ! is_array($hook))
 97         {
 98             return;
 99         }
100 
101         $this->hooks =& $hook;//include(hook.php),将文件里定义的hook数组引用到$this->hooks
102         $this->enabled = TRUE;
103     }
104 
105     // --------------------------------------------------------------------
106 
107     /**
108      * Call Hook
109      * 外部其实就是调用这个_call_hook函数进行调用钩子程序。而此方法中再调用_run_hook去执行相应的钩子
110      * Calls a particular hook
111      *
112      * @access    private
113      * @param    string    the hook name
114      * @return    mixed
115      */
116     function _call_hook($which = '')
117     {
118         if ( ! $this->enabled OR ! isset($this->hooks[$which]))////以pre_system挂钩点为例,当调用_call_hook('pre_system')时
119         {
120             return FALSE;////确保$this->enable = TRUE && 定义了$this->hooks['pre_system']
121         }
122 // //如果是二维数组就遍历,依次_run_hook($this->hooks['pre_system'][$val])
123         if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
124         {
125             foreach ($this->hooks[$whichas $val)
126             {
127                 $this->_run_hook($val);
128             }
129         }
130         else //如果是一维数组,那么直接_run_hook($this->hooks['pre_system']) //同一个位置可以执行多个hook
131         {
132             $this->_run_hook($this->hooks[$which]);
133         }
134 
135         return TRUE;
136     }
137 
138     // --------------------------------------------------------------------
139 
140     /**
141      * Run Hook 取得 hook.php中配置并组装成对应的类 函数 参数类执行
142      *
143      * Runs a particular hook
144      *
145      * @access    private
146      * @param    array    the hook details
147      * @return    bool
148      */
149     function _run_hook($data)
150     {
151         if ( ! is_array($data))//$data 是传递过来的hook数组
152         {
153             return FALSE;
154         }
155     //$data 就是我们在APPPATH/config/hook.php 定义的hook数组
156         //$hook['pre_controller'] = array(
157                 //               'class'    => 'MyClass',
158                 //                'function' => 'Myfunction',
159                 //               'filename' => 'Myclass.php',
160                 //                'filepath' => 'hooks',
161                 //                'params'   => array('beer', 'wine', 'snacks')
162                 //                );
163         
164         // -----------------------------------
165         // Safety - Prevents run-away loops
166         // -----------------------------------
167 
168         // If the script being called happens to have the same
169         // hook call within it a loop can happen
170 
171         if ($this->in_progress == TRUE)
172         {
173             return;
174         }
175 
176         // -----------------------------------
177         // Set file path
178         // -----------------------------------
179 
180         if ( ! isset($data['filepath']) OR ! isset($data['filename']))
181         {
182             return FALSE;
183         }
184 
185         $filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
186 
187         if ( ! file_exists($filepath))
188         {
189             return FALSE;
190         }
191 
192         // -----------------------------------
193         // Set class/function name
194         // -----------------------------------
195 
196         /**
197          * 取出data里面的数据,加载  APPPATH.$data['filepath'].$data['filename'];
198             实例化钩子类,调用function。应用到示例中就是
199             $this->in_process = TRUE;
200             $Hook = new  MyClass();
201             $Hook->Myfunction($params);
202             $this->in_process = FALSE;
203          */
204         
205         $class        = FALSE;
206         $function    = FALSE;
207         $params        = '';
208 
209         if (isset($data['class']) AND $data['class'] != '')
210         {
211             $class = $data['class'];
212         }
213 
214         if (isset($data['function']))
215         {
216             $function = $data['function'];
217         }
218 
219         if (isset($data['params']))
220         {
221             $params = $data['params'];
222         }
223 
224         if ($class === FALSE AND $function === FALSE)
225         {
226             return FALSE;
227         }
228 
229         // -----------------------------------
230         // Set the in_progress flag
231         // -----------------------------------
232 
233         $this->in_progress = TRUE;
234 
235         // -----------------------------------
236         // Call the requested class and/or function
237         // -----------------------------------
238 
239         if ($class !== FALSE)
240         {
241             if ( ! class_exists($class))
242             {
243                 require($filepath);
244             }
245 
246             $HOOK = new $class;
247             $HOOK->$function($params);
248         }
249         else
250         {
251             if ( ! function_exists($function))
252             {
253                 require($filepath);
254             }
255 
256             $function($params);
257         }
258 
259         $this->in_progress = FALSE;
260         return TRUE;
261     }
262 
263 }
264 
265 // END CI_Hooks class
266 
267 /* End of file Hooks.php */
268 /* Location: ./system/core/Hooks.php */
posted @ 2012-11-20 10:49  Linux、Mongo、Php、Shell、Python、C  阅读(265)  评论(0编辑  收藏  举报