php框架codeigniter框架源代码分析,注释中文化,类库分析(一)
最近这几天决定看 ci框架的源代码的,因为它是轻量级的,代码文件的结构比较清晰,又index.php作为入口,在codeigniter.php文件中加载所有的基础类,于是我挨个类滴看下去,并且在看的时候分析了每一步关键的进程,而且对原来的英文注释进行了翻译,现在主要文件已经翻译完成,稍候会翻译并分析一些其他的重要的类,敬请期待
这里的是 它的详细的执行过程,从入口到最后结束,进行了完整的记录,大家先看着,其他的分析,例如,CI超类的结构,如何实现MVC模式,数据库类的实现,xss过滤类的详细分析等等内容以后陆续会登陆
从这里下载源文件:/Files/mier/ci的执行流程.txt 下载后把文件后缀改为 .php即可正常在ide里浏览
1 <?php
2 //约定:变量后圆括号内为变量的含义,方括号为变量的值
3 1.index.php.
4 (1),初始化一些系统变量,包括:
5 $system_folder(系统文件夹[system]),
6 $application_folder(应用程序文件夹[application])
7 (2).定义一些常量,包括:
8 EXT(文件扩展名[pathinfo(__FILE__, PATHINFO_EXTENSION)]),
9 FCPATH(文件在服务器中的完整路径名[__FILE__]),
10 SELF(包含扩展名的文件名[pathinfo(__FILE__, PATHINFO_BASENAME)]),
11 BASEPATH(系统文件夹的路径[$system_folder.'/']),
12 APPPATH(程序所在文件夹[$application_folder.'/']),
13 (3).定向至
14 BASEPATH.'codeigniter/CodeIgniter'.EXT;
15 (4).结束
16 ?>
17 <?php
18 2.CodeIgniter.php(系统前台控制器,加载基本类和处理请求)
19 (1),加载全局函数,这些全局函数在后面的加载类和获取配置项方面发挥作用,
20 require(BASEPATH.'codeigniter/Common'.EXT);
21 Common.php中拥有如下函数:
22 is_really_writable($file);//判断文件是否可写
23 &load_class($class, $instantiate = TRUE)//这个函数利用单件模式,当请求的class不存在时就加载这个类,然后将其设置成一个静态变量,如果已经加载了这个类,则返回这个类的安装变量
24 //第二个参数指示,是否实例化此类,如果设置为false,则只是包含此类的文件而不进行实例化,返回的值为true/false只是是否加载成功
25 //从libraries中加载类库
26 &get_config()//返回config.php文件中的配置数组
27 config_item($item) //获取某个配置项
28 show_error($message)//显示错误
29 show_404($page = '')//显示404错误
30 log_message($level = 'error', $message, $php_error = FALSE)//将信息写入日志
31 _exception_handler($severity, $message, $filepath, $line)//错误处理函数,可以拦截错误并写入到指定的文件中
32 (2),兼容性函数 ,处理一些在某些版本中不存在的函数
33 require(BASEPATH.'codeigniter/Compat'.EXT);
34 Compat.php中存在下列内容:
35 定义了错误显示级别:define('E_STRICT', 2048);
36 定义了函数:ctype_digit($str)//字符串中只包含数字,否则返回false
37 定义了函数:ctype_alnum($str);//字符串中只包含数字或者字母,否则返回false
38 (3).加载框架常量
39 require(APPPATH.'config/constants'.EXT);
40 此文件中定义的常量具体见文件中,此处省略
41 (4).设置错误处理,禁用magic_quotes_runtime
42 (5).导入benchmark类,设置断点并调试断点,这个类使你可以设置断点来计算运行时间和消耗的内存
43 $BM =& load_class('Benchmark');
44 Benchmark类中有下列属性和方法:
45 var $marker = array();//断点的数组
46 function mark($name)//设置一个断点,将现在的时间以微秒标识赋值给此变量
47 function elapsed_time($point1 = '', $point2 = '', $decimals = 4)//计算两个断点的间隔时间,如果第一个断点的值为空,则返回一个标签{elapsed_time},在output类中将处理这个标签
48 function memory_usage()//返回一个{memory_usage}标签,在output类中将处理这个标签,因为显示整个脚本的消耗内存量才是有意义的
49 (6).加载钩子类,提供了一种机制来扩展基本系统的运行方式,即在某些点插入你自己要运行的脚本,包括诸多可选点
50 $EXT =& load_class('Hooks');
51 此类包含如下的属性和方法:
52 var $enabled = FALSE;//是否启用钩子
53 var $hooks = array();//钩子数组
54 var $in_progress = FALSE;//标识是否正在运行钩子
55 function _initialize()//判断是否启用hooks,如果启用的话就在config/hooks.php中加载hooks,并赋给$hooks属性
56 function _call_hook($which = '')//调用钩子,可以设置的钩子是有限的,见此文件中的类库说明
57 function _run_hook($data)//运行钩子,根据钩子的设置数组来包含文件,实例化类,运行其方法,以及附加属性
58 (7).加载并实例化Config类,从config文件夹加载配置文件,也就是允许你在config文件夹中建立自己的配置文件,但是在此文件中必须以$config[""]数组的形式定义配置项
59 $CFG =& load_class('Config');
60 此类包含如下属性和方法:
61 var $config = array();//config数组
62 var $is_loaded = array();//已经加载的配置文件
63 function CI_Config()//构造函数,获取config.php中的基本config项并赋值给$config属性
64 function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)//从config文件夹中加载配置文件(加载成功添加至$is_loaded属性),并加载配置项至$config属性
65 function item($item, $index = '')//返回某个配置项,$index允许配置以二维数组的形式出现,当配置为二维数组的时候,则用$config[$index][$item]
66 function slash_item($item)//获取一个配置项,并在其后加上一个"/"符号
67 function site_url($uri = '')//根据config设置将uri转化成完整的url形式
68 function system_url()//返回系统文件夹的完整路径
69 function set_item($item, $value)//设置某个设置项的值,只是设置在属性里,不会更改文件的设置
70 (8).加载并实例化URI类,此类将截取当前url的参数部分,并分解成控制器以及方法以及参数,供主函数调用
71 $URI =& load_class('URI');
72 此类包含如下属性和方法:
73 var $keyval = array();
74 var $uri_string;//index.php后面的字符串
75 var $segments = array();
76 var $rsegments = array();
77 function _fetch_uri_string()//得到index.php后面的字符串并赋值给属性 $uri_string.
78 function _parse_request_uri()//处理uri中的骚扰字符,使其能正常工作
79 function _filter_uri($str)//过滤字符串,对特殊字符进行转义
80 function _remove_url_suffix()//如果在配置中设置了伪后缀名,则去掉这个后缀
81 function _explode_segments()//将字符串按"/"分解到$segments中
82 function _reindex_segments()//利用巧妙的方法改变$segments数组的索引,使其索引从1开始,这样更符合直观感受
83 function segment($n, $no_result = FALSE)//返回指定索引的参数,即$segments[$n]的值
84 function rsegment($n, $no_result = FALSE)//这个函数和上面的函数基本功能一样,不同点在于它允许你在开启CodeIgniter的URI路由功能时进行详细分割并重新分发URI信息
85 function uri_to_assoc($n = 3, $default = array())//将第三个参数之后的参数以关联数组的方式返回 其中第三个参数是第一个返回数组的key,第四个参数是第一个返回数组的value
86 //以此类推
87 function ruri_to_assoc($n = 3, $default = array())//同上,只是应用于路由功能
88 function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')//同上
89 function assoc_to_uri($array)//与上述方法的功能相反
90 function _slash_segment($n, $where = 'trailing', $which = 'segment')//添加斜线,当$where="trailing"时在末尾添加,="leading"时在开头添加
91 function segment_array()//返回$segments
92 function total_segments()//$segments的总数
93 (9).加载并实例化Router类,这个类处理uri来加载控制器和控制器方法
94 $RTR =& load_class('Router');
95 此类包含如下属性和方法:
96 var $config;
97 var $routes = array();//路由规则,在routes.php中定义
98 var $error_routes = array();
99 var $class = '';
100 var $method = 'index';
101 var $directory = '';
102 var $uri_protocol = 'auto';
103 var $default_controller;//默认的控制器
104 var $scaffolding_request = FALSE; // Must be set to FALSE
105 function _set_routing()//设置默认的路由信息,如果不存在控制器信息,则根据routes.php的设置来加载默认的控制器,
106 function _set_request($segments = array())//这个方法以一个数组输入来调用set_class和set_method来发送请求
107 function _validate_request($segments)//检查是否在uri中包含了文件夹信息,如果包含,则将其值赋给属性$directory
108 function _parse_routes()//处理路由,根据路由设置来
109 function set_class($class)//设置控制器类
110 function fetch_class()
111 function set_method($method)//设置控制器方法
112 function fetch_method()
113 function set_directory($dir)//设置文件夹
114 (10).加载并实例化Output类
115 $OUT =& load_class('Output');
116 此类包含如下的方法和属性:
117 var $final_output;
118 var $cache_expiration = 0;
119 var $headers = array();
120 var $enable_profiler = FALSE;
121 function enable_profiler($val = TRUE)//允许你开启或禁用评测器,评测器将在页的底部显示测试基准点或调试、优化需要的其他数据
122 function get_output()
123 function set_output($output)
124 function append_output($output)//附加输出的内容
125 function set_header($header, $replace = TRUE)//设置要发送的header到数组属性 $headers
126 function set_status_header($code = '200', $text = '')//设置状态码
127 function cache($time)//设置缓存以及缓存时间 ,以分钟为单位
128 function _display($output = '')//这个方法将生成并输出至客户端,如果开启了profiler则在页尾添加性能分析结果,如果设置了缓存,则调用缓存文件
129 function _write_cache($output)//根据设置的缓存时间写缓存文件
130 function _display_cache(&$CFG, &$URI)//显示缓存文件,根据url寻找文件(md5加密形式的文件名),如果存在则显示,如果过期,则删除
131 (11).判断是否存在缓存文件,如果存在则显示,并退出
132 (12).加载input类,这个类用来处理过滤用户的输入,防止产生各种攻击
133 $IN =& load_class('Input');
134 var $use_xss_clean = FALSE;
135 var $xss_hash = '';
136 var $ip_address = FALSE;
137 var $user_agent = FALSE;
138 var $allow_get_array = FALSE;
139 var $never_allowed_str = array()//过滤的字符串,详细见类文件定义
140 var $never_allowed_regex =array()//用正则过滤,详细见类文件定义
141 function CI_Input()//构造函数,从配置文件判断是否开启安全功能,然后调用下面的方法
142 function _sanitize_globals()//清除globals变量,在开启了globals_register的情况下,相当于关闭了此配置项
143 function _clean_input_data($str)//过滤输入的数据
144 function _clean_input_keys($str)//过滤键值
145 function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)//从$array获取值,如果设置了xss_clean则过滤之
146 function get($index = '', $xss_clean = FALSE)//获取过滤后的get数组
147 function post($index = '', $xss_clean = FALSE)//获取过滤后的post数组
148 function get_post($index = '', $xss_clean = FALSE)//获取post数组,如果没有则从get数组获取
149 function cookie($index = '', $xss_clean = FALSE)//获取cookie数组
150 function server($index = '', $xss_clean = FALSE)//获取服务器变量数组
151 function ip_address()//获取ip地址
152 function valid_ip($ip)//验证ip地址
153 function filename_security($str)//过滤文件名中的隐患
154 function xss_clean($str, $is_image = FALSE)//执行各种xss过滤
155 function _remove_invisible_characters($str)//移除不可见的符号
156 省略了一系列xss_clean中的回调函数,对输入执行各种安全过滤
157 (13).加载language类
158 $LANG =& load_class('Language');
159 省略此类的描述
160 (14).加载controller类
161 load_class('Controller', FALSE);
162 只包含此文件而不实例化此类
163 如果php版本小于5则加载loader类
164 (15).根据uri来在controller文件夹中寻找控制器类和方法,如果找不到则退出,找到则包含文件
165 $class = $RTR->fetch_class();//获取请求的类
166 $method = $RTR->fetch_method();//获取请求的方法
167 (16).
168 (17).$CI = new $class();//加载超类,超类是以控制器中的类为基础创建的
169 判断是否是附带脚手架的请求
170 (18)Controller类的结构:此类继承自CI_Base类
171 var $_ci_scaffolding = FALSE;
172 var $_ci_scaff_table = FALSE;
173 function Controller()//构造函数,执行parent::CI_Base();$this->_ci_initialize();
174 function _ci_initialize()//在此将所有的基本类都加在为这个类的变量,使本类成为一个超级类,并且加载load类来加载视图和模型等
175 function _ci_scaffolding()//执行脚手架
176 (19).如果使用了数据库 则关闭数据库
177
178
179
2 //约定:变量后圆括号内为变量的含义,方括号为变量的值
3 1.index.php.
4 (1),初始化一些系统变量,包括:
5 $system_folder(系统文件夹[system]),
6 $application_folder(应用程序文件夹[application])
7 (2).定义一些常量,包括:
8 EXT(文件扩展名[pathinfo(__FILE__, PATHINFO_EXTENSION)]),
9 FCPATH(文件在服务器中的完整路径名[__FILE__]),
10 SELF(包含扩展名的文件名[pathinfo(__FILE__, PATHINFO_BASENAME)]),
11 BASEPATH(系统文件夹的路径[$system_folder.'/']),
12 APPPATH(程序所在文件夹[$application_folder.'/']),
13 (3).定向至
14 BASEPATH.'codeigniter/CodeIgniter'.EXT;
15 (4).结束
16 ?>
17 <?php
18 2.CodeIgniter.php(系统前台控制器,加载基本类和处理请求)
19 (1),加载全局函数,这些全局函数在后面的加载类和获取配置项方面发挥作用,
20 require(BASEPATH.'codeigniter/Common'.EXT);
21 Common.php中拥有如下函数:
22 is_really_writable($file);//判断文件是否可写
23 &load_class($class, $instantiate = TRUE)//这个函数利用单件模式,当请求的class不存在时就加载这个类,然后将其设置成一个静态变量,如果已经加载了这个类,则返回这个类的安装变量
24 //第二个参数指示,是否实例化此类,如果设置为false,则只是包含此类的文件而不进行实例化,返回的值为true/false只是是否加载成功
25 //从libraries中加载类库
26 &get_config()//返回config.php文件中的配置数组
27 config_item($item) //获取某个配置项
28 show_error($message)//显示错误
29 show_404($page = '')//显示404错误
30 log_message($level = 'error', $message, $php_error = FALSE)//将信息写入日志
31 _exception_handler($severity, $message, $filepath, $line)//错误处理函数,可以拦截错误并写入到指定的文件中
32 (2),兼容性函数 ,处理一些在某些版本中不存在的函数
33 require(BASEPATH.'codeigniter/Compat'.EXT);
34 Compat.php中存在下列内容:
35 定义了错误显示级别:define('E_STRICT', 2048);
36 定义了函数:ctype_digit($str)//字符串中只包含数字,否则返回false
37 定义了函数:ctype_alnum($str);//字符串中只包含数字或者字母,否则返回false
38 (3).加载框架常量
39 require(APPPATH.'config/constants'.EXT);
40 此文件中定义的常量具体见文件中,此处省略
41 (4).设置错误处理,禁用magic_quotes_runtime
42 (5).导入benchmark类,设置断点并调试断点,这个类使你可以设置断点来计算运行时间和消耗的内存
43 $BM =& load_class('Benchmark');
44 Benchmark类中有下列属性和方法:
45 var $marker = array();//断点的数组
46 function mark($name)//设置一个断点,将现在的时间以微秒标识赋值给此变量
47 function elapsed_time($point1 = '', $point2 = '', $decimals = 4)//计算两个断点的间隔时间,如果第一个断点的值为空,则返回一个标签{elapsed_time},在output类中将处理这个标签
48 function memory_usage()//返回一个{memory_usage}标签,在output类中将处理这个标签,因为显示整个脚本的消耗内存量才是有意义的
49 (6).加载钩子类,提供了一种机制来扩展基本系统的运行方式,即在某些点插入你自己要运行的脚本,包括诸多可选点
50 $EXT =& load_class('Hooks');
51 此类包含如下的属性和方法:
52 var $enabled = FALSE;//是否启用钩子
53 var $hooks = array();//钩子数组
54 var $in_progress = FALSE;//标识是否正在运行钩子
55 function _initialize()//判断是否启用hooks,如果启用的话就在config/hooks.php中加载hooks,并赋给$hooks属性
56 function _call_hook($which = '')//调用钩子,可以设置的钩子是有限的,见此文件中的类库说明
57 function _run_hook($data)//运行钩子,根据钩子的设置数组来包含文件,实例化类,运行其方法,以及附加属性
58 (7).加载并实例化Config类,从config文件夹加载配置文件,也就是允许你在config文件夹中建立自己的配置文件,但是在此文件中必须以$config[""]数组的形式定义配置项
59 $CFG =& load_class('Config');
60 此类包含如下属性和方法:
61 var $config = array();//config数组
62 var $is_loaded = array();//已经加载的配置文件
63 function CI_Config()//构造函数,获取config.php中的基本config项并赋值给$config属性
64 function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)//从config文件夹中加载配置文件(加载成功添加至$is_loaded属性),并加载配置项至$config属性
65 function item($item, $index = '')//返回某个配置项,$index允许配置以二维数组的形式出现,当配置为二维数组的时候,则用$config[$index][$item]
66 function slash_item($item)//获取一个配置项,并在其后加上一个"/"符号
67 function site_url($uri = '')//根据config设置将uri转化成完整的url形式
68 function system_url()//返回系统文件夹的完整路径
69 function set_item($item, $value)//设置某个设置项的值,只是设置在属性里,不会更改文件的设置
70 (8).加载并实例化URI类,此类将截取当前url的参数部分,并分解成控制器以及方法以及参数,供主函数调用
71 $URI =& load_class('URI');
72 此类包含如下属性和方法:
73 var $keyval = array();
74 var $uri_string;//index.php后面的字符串
75 var $segments = array();
76 var $rsegments = array();
77 function _fetch_uri_string()//得到index.php后面的字符串并赋值给属性 $uri_string.
78 function _parse_request_uri()//处理uri中的骚扰字符,使其能正常工作
79 function _filter_uri($str)//过滤字符串,对特殊字符进行转义
80 function _remove_url_suffix()//如果在配置中设置了伪后缀名,则去掉这个后缀
81 function _explode_segments()//将字符串按"/"分解到$segments中
82 function _reindex_segments()//利用巧妙的方法改变$segments数组的索引,使其索引从1开始,这样更符合直观感受
83 function segment($n, $no_result = FALSE)//返回指定索引的参数,即$segments[$n]的值
84 function rsegment($n, $no_result = FALSE)//这个函数和上面的函数基本功能一样,不同点在于它允许你在开启CodeIgniter的URI路由功能时进行详细分割并重新分发URI信息
85 function uri_to_assoc($n = 3, $default = array())//将第三个参数之后的参数以关联数组的方式返回 其中第三个参数是第一个返回数组的key,第四个参数是第一个返回数组的value
86 //以此类推
87 function ruri_to_assoc($n = 3, $default = array())//同上,只是应用于路由功能
88 function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')//同上
89 function assoc_to_uri($array)//与上述方法的功能相反
90 function _slash_segment($n, $where = 'trailing', $which = 'segment')//添加斜线,当$where="trailing"时在末尾添加,="leading"时在开头添加
91 function segment_array()//返回$segments
92 function total_segments()//$segments的总数
93 (9).加载并实例化Router类,这个类处理uri来加载控制器和控制器方法
94 $RTR =& load_class('Router');
95 此类包含如下属性和方法:
96 var $config;
97 var $routes = array();//路由规则,在routes.php中定义
98 var $error_routes = array();
99 var $class = '';
100 var $method = 'index';
101 var $directory = '';
102 var $uri_protocol = 'auto';
103 var $default_controller;//默认的控制器
104 var $scaffolding_request = FALSE; // Must be set to FALSE
105 function _set_routing()//设置默认的路由信息,如果不存在控制器信息,则根据routes.php的设置来加载默认的控制器,
106 function _set_request($segments = array())//这个方法以一个数组输入来调用set_class和set_method来发送请求
107 function _validate_request($segments)//检查是否在uri中包含了文件夹信息,如果包含,则将其值赋给属性$directory
108 function _parse_routes()//处理路由,根据路由设置来
109 function set_class($class)//设置控制器类
110 function fetch_class()
111 function set_method($method)//设置控制器方法
112 function fetch_method()
113 function set_directory($dir)//设置文件夹
114 (10).加载并实例化Output类
115 $OUT =& load_class('Output');
116 此类包含如下的方法和属性:
117 var $final_output;
118 var $cache_expiration = 0;
119 var $headers = array();
120 var $enable_profiler = FALSE;
121 function enable_profiler($val = TRUE)//允许你开启或禁用评测器,评测器将在页的底部显示测试基准点或调试、优化需要的其他数据
122 function get_output()
123 function set_output($output)
124 function append_output($output)//附加输出的内容
125 function set_header($header, $replace = TRUE)//设置要发送的header到数组属性 $headers
126 function set_status_header($code = '200', $text = '')//设置状态码
127 function cache($time)//设置缓存以及缓存时间 ,以分钟为单位
128 function _display($output = '')//这个方法将生成并输出至客户端,如果开启了profiler则在页尾添加性能分析结果,如果设置了缓存,则调用缓存文件
129 function _write_cache($output)//根据设置的缓存时间写缓存文件
130 function _display_cache(&$CFG, &$URI)//显示缓存文件,根据url寻找文件(md5加密形式的文件名),如果存在则显示,如果过期,则删除
131 (11).判断是否存在缓存文件,如果存在则显示,并退出
132 (12).加载input类,这个类用来处理过滤用户的输入,防止产生各种攻击
133 $IN =& load_class('Input');
134 var $use_xss_clean = FALSE;
135 var $xss_hash = '';
136 var $ip_address = FALSE;
137 var $user_agent = FALSE;
138 var $allow_get_array = FALSE;
139 var $never_allowed_str = array()//过滤的字符串,详细见类文件定义
140 var $never_allowed_regex =array()//用正则过滤,详细见类文件定义
141 function CI_Input()//构造函数,从配置文件判断是否开启安全功能,然后调用下面的方法
142 function _sanitize_globals()//清除globals变量,在开启了globals_register的情况下,相当于关闭了此配置项
143 function _clean_input_data($str)//过滤输入的数据
144 function _clean_input_keys($str)//过滤键值
145 function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)//从$array获取值,如果设置了xss_clean则过滤之
146 function get($index = '', $xss_clean = FALSE)//获取过滤后的get数组
147 function post($index = '', $xss_clean = FALSE)//获取过滤后的post数组
148 function get_post($index = '', $xss_clean = FALSE)//获取post数组,如果没有则从get数组获取
149 function cookie($index = '', $xss_clean = FALSE)//获取cookie数组
150 function server($index = '', $xss_clean = FALSE)//获取服务器变量数组
151 function ip_address()//获取ip地址
152 function valid_ip($ip)//验证ip地址
153 function filename_security($str)//过滤文件名中的隐患
154 function xss_clean($str, $is_image = FALSE)//执行各种xss过滤
155 function _remove_invisible_characters($str)//移除不可见的符号
156 省略了一系列xss_clean中的回调函数,对输入执行各种安全过滤
157 (13).加载language类
158 $LANG =& load_class('Language');
159 省略此类的描述
160 (14).加载controller类
161 load_class('Controller', FALSE);
162 只包含此文件而不实例化此类
163 如果php版本小于5则加载loader类
164 (15).根据uri来在controller文件夹中寻找控制器类和方法,如果找不到则退出,找到则包含文件
165 $class = $RTR->fetch_class();//获取请求的类
166 $method = $RTR->fetch_method();//获取请求的方法
167 (16).
168 (17).$CI = new $class();//加载超类,超类是以控制器中的类为基础创建的
169 判断是否是附带脚手架的请求
170 (18)Controller类的结构:此类继承自CI_Base类
171 var $_ci_scaffolding = FALSE;
172 var $_ci_scaff_table = FALSE;
173 function Controller()//构造函数,执行parent::CI_Base();$this->_ci_initialize();
174 function _ci_initialize()//在此将所有的基本类都加在为这个类的变量,使本类成为一个超级类,并且加载load类来加载视图和模型等
175 function _ci_scaffolding()//执行脚手架
176 (19).如果使用了数据库 则关闭数据库
177
178
179