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[$which] as $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 */
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[$which] as $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 */