核心 « 邵珠庆の博客

邵珠庆の博客 生命只有一次,你可以用它来做些更多伟大的事情–Make the world a little better and easier

27二/130

CI框架源码完全分析之核心文件Codeigniter.php

发布在 邵珠庆


Warning: fopen(/home1/vhost/vh499565/www/www_shaozhuqing/wp-content/plugins/devformatter/geshi/geshi/php.php): failed to open stream: No such file or directory in /home1/vhost/vh499565/www/www1/wp-content/plugins/devformatter/devgeshi.php on line 103

Warning: fopen(/home1/vhost/vh499565/www/www_shaozhuqing/wp-content/plugins/devformatter/geshi/geshi/php.php): failed to open stream: No such file or directory in /home1/vhost/vh499565/www/www1/wp-content/plugins/devformatter/devgeshi.php on line 103

Warning: fopen(/home1/vhost/vh499565/www/www_shaozhuqing/wp-content/plugins/devformatter/geshi/geshi/php.php): failed to open stream: No such file or directory in /home1/vhost/vh499565/www/www1/wp-content/plugins/devformatter/devgeshi.php on line 103

 php | 
 
 copy code |
?

001
<?php  
002
/**
003
 * 转载请保留链接
004
 * @link http://www.phpddt.com
005
 */
006
//如果入口文件系统目录常量BASEPATH没定义,就挂了
007
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
008
        //定义常量:CI_VERSION,CI_CORE
009
 define('CI_VERSION', '2.1.4');
010
 define('CI_CORE', FALSE);
011
 
012
/*
013
 *引入系统目录下core/Common.php,这里面全是CI的系统全局函数如is_php()、load_class()等
014
 */
015
 require(BASEPATH.'core/Common.php');
016
 
017
/*
018
 *加载应用目录下的常量,注意如果存在相应的开发环境目录,则加载对应目录下的文件,ENVIRONMENT实在入口文件定义的
019
 */
020
 
021
 if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
022
 {
023
 require(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
024
 }
025
 else
026
 {
027
 require(APPPATH.'config/constants.php');
028
 }
029
 
030
/*
031
 *_exception_handler函数是刚才在Common.php中加载的函数,用来拦截错误,记录日志,
032
 * set_error_handler是在_exception_handler函数中用load_class加载过来的。
033
 */
034
 set_error_handler('_exception_handler');
035
        //关闭magic quotes,关于这个的详细介绍请看:http://www.phpddt.com/php/php-magic-quotes.html
036
 if ( ! is_php('5.3'))
037
 {
038
 @set_magic_quotes_runtime(0); // Kill magic quotes
039
 }
040
 
041
/*
042
 *子类前缀,很重要,也就是说你可以去扩展CI核心类,后面说,默认配置应该是MY_
043
 */
044
        //看看你在index.php中是否定义前缀,没有定义的话就加载配置文件获知,get_config是Common.php中的全局函数
045
 if (isset($assign_to_config['subclass_prefix']) AND $assign_to_config['subclass_prefix'] != '')
046
 {
047
 get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
048
 }
049
 
050
/*
051
 *php 程序运行默认是30s,这里用set_time_limt延长了,关于set_time_Limit() http://www.phpddt.com/php/set_time_limit.html
052
 * 扩展阅读,关于safe_mode:http://www.phpddt.com/php/643.html  ,你会完全明白的
053
 */
054
 if (function_exists("set_time_limit") == TRUE AND @ini_get("safe_mode") == 0)
055
 {
056
 @set_time_limit(300);
057
 }
058
 
059
/*
060
 * 加载Benchmark,它很简单,就是计算任意两点之间程序的运行时间
061
 */
062
 $BM =& load_class('Benchmark', 'core');
063
 $BM->mark('total_execution_time_start');
064
 $BM->mark('loading_time:_base_classes_start');
065
 
066
        //加载钩子,后期会分析到,这玩意特好,扩展它能改变CI的运行流程
067
 $EXT =& load_class('Hooks', 'core');
068
 
069
        //这里就是一个钩子啦,其实就是该钩子程序在这里执行
070
 $EXT->_call_hook('pre_system');
071
 
072
        //加载配置文件,这里面都是一些加载或获取配置信息的函数
073
 $CFG =& load_class('Config', 'core');
074
 
075
 // 如果在index.php中也有配置$assign_to_config,则也把它加入到$CFG
076
 if (isset($assign_to_config))
077
 {
078
 $CFG->_assign_to_config($assign_to_config);
079
 }
080
 
081
        //加载utf8组件、URI组件、Router组件
082
 $UNI =& load_class('Utf8', 'core');
083
 $URI =& load_class('URI', 'core');
084
 $RTR =& load_class('Router', 'core');
085
 $RTR->_set_routing();
086
 
087
 //如果在index.php中定义了$routing,那么就会覆盖上面路由
088
 if (isset($routing))
089
 {
090
 $RTR->_set_overrides($routing);
091
 }
092
 
093
        //加载output输出组件,不然你怎么用$this->Load->view()啊
094
 $OUT =& load_class('Output', 'core');
095
 
096
        //又见钩子,这里你可以自己写钩子程序替代Output类的缓存输出
097
 if ($EXT->_call_hook('cache_override') === FALSE)
098
 {
099
 if ($OUT->_display_cache($CFG, $URI) == TRUE)
100
 {
101
 exit;
102
 }
103
 }
104
 
105
        //安全组件啦,防xss攻击啊,csrf攻击啊
106
        //关于xss攻击:http://www.phpddt.com/php/php-prevent-xss.html
107
        //关于csrf:攻击:http://www.phpddt.com/reprint/csrf.html
108
 $SEC =& load_class('Security', 'core');
109
 
110
        //加载输入组件,就是你常用的$this->input->post();等
111
 $IN =& load_class('Input', 'core');
112
 
113
        //加载语言组件啦
114
 $LANG =& load_class('Lang', 'core');
115
 
116
        //引入CI的控制器父类
117
 require BASEPATH.'core/Controller.php';
118
 
119
 function &get_instance()
120
 {
121
 return CI_Controller::get_instance();
122
 }
123
 
124
        //当然你扩展了CI_Controller控制器的话,也要引入啦
125
 if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
126
 {
127
 require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
128
 }
129
 
130
 //加载你自己应用中的控制器Controller,如果没有当然error啦
131
 if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php'))
132
 {
133
 show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
134
 }
135
 include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
136
 
137
 // 好的基础的类都加载完毕了,咱可以mark一下
138
 $BM->mark('loading_time:_base_classes_end');
139
 
140
        //路由获取了控制器名和方法名,比如说默认welcome/index
141
 $class  = $RTR->fetch_class();
142
 $method = $RTR->fetch_method();
143
        //这里CI规定一般非公共的方法以_开头,下面是判断,如果URI不可访问就show_404()
144
 if ( ! class_exists($class)
145
 OR strncmp($method, '_', 1) == 0
146
 OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
147
 )
148
 {
149
 if ( ! empty($RTR->routes['404_override']))
150
 {
151
 $x = explode('/', $RTR->routes['404_override']);
152
 $class = $x[0];
153
 $method = (isset($x[1]) ? $x[1] : 'index');
154
 if ( ! class_exists($class))
155
 {
156
 if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
157
 {
158
 show_404("{$class}/{$method}");
159
 }
160
 
161
 include_once(APPPATH.'controllers/'.$class.'.php');
162
 }
163
 }
164
 else
165
 {
166
 show_404("{$class}/{$method}");
167
 }
168
 }
169
 
170
        //又是钩子,该钩子发生在控制器实例化之前的
171
 $EXT->_call_hook('pre_controller');
172
 
173
        //又mark一个点
174
 $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
175
        //终于实例化控制器了
176
 $CI = new $class();
177
 
178
        //钩子,不想多说了
179
 $EXT->_call_hook('post_controller_constructor');
180
 
181
/*
182
 * ------------------------------------------------------
183
 *  Call the requested method
184
 * ------------------------------------------------------
185
 */
186
 // Is there a "remap" function? If so, we call it instead
187
 if (method_exists($CI, '_remap'))
188
 {
189
 $CI->_remap($method, array_slice($URI->rsegments, 2));
190
 }
191
 else
192
 {
193
 // is_callable() returns TRUE on some versions of PHP 5 for private and protected
194
 // methods, so we'll use this workaround for consistent behavior
195
 if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))
196
 {
197
 // Check and see if we are using a 404 override and use it.
198
 if ( ! empty($RTR->routes['404_override']))
199
 {
200
 $x = explode('/', $RTR->routes['404_override']);
201
 $class = $x[0];
202
 $method = (isset($x[1]) ? $x[1] : 'index');
203
 if ( ! class_exists($class))
204
 {
205
 if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
206
 {
207
 show_404("{$class}/{$method}");
208
 }
209
 
210
 include_once(APPPATH.'controllers/'.$class.'.php');
211
 unset($CI);
212
 $CI = new $class();
213
 }
214
 }
215
 else
216
 {
217
 show_404("{$class}/{$method}");
218
 }
219
 }
220
 
221
 // 终于调用方法了,$this->load->view()把内容放到缓存区
222
 call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
223
 }
224
 $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
225
 $EXT->_call_hook('post_controller');
226
 
227
        //这里就是把缓存区的内容输出了
228
 if ($EXT->_call_hook('display_override') === FALSE)
229
 {
230
 
231
 $OUT->_display();
232
 }
233
 
234
 $EXT->_call_hook('post_system');
235
        //关闭数据库的链接
236
 if (class_exists('CI_DB') AND isset($CI->db))
237
 {
238
 $CI->db->close();
239
 }

 
[......]阅读全文