我们都知道CodeIgniter是单点接入,网上的教材很多,但是具体得 流程怎样,感觉不是很详细,因此这里我们利用PHP的magic 常量来查看CI程序的程序流程图。我们利用的magic 常量就是__FILE__,该变量是打印当前正在运行的文件。这里我在每一个文件都加入该变量,我们使用批量文件修改所有的文件内容,批量脚本内见下面。
剩下的内容就是
你将看到如下的流程的时间流:(微妙级别)
-
EXECUTE TIME: 24-14-04-33:0.43059600 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\CodeIgniter.php
-
EXECUTE TIME: 24-14-04-33:0.43226000 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Common.php
-
EXECUTE TIME: 24-14-04-33:0.43405000 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Benchmark.php
-
EXECUTE TIME: 24-14-04-33:0.43632500 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Hooks.php
-
EXECUTE TIME: 24-14-04-33:0.43777000 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Config.php
-
EXECUTE TIME: 24-14-04-33:0.43885000 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Utf8.php
-
EXECUTE TIME: 24-14-04-33:0.44086900 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\URI.php
-
EXECUTE TIME: 24-14-04-33:0.44311600 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Router.php
-
EXECUTE TIME: 24-14-04-33:0.44620600 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Output.php
-
EXECUTE TIME: 24-14-04-33:0.44997300 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Security.php
-
EXECUTE TIME: 24-14-04-33:0.45253500 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Input.php
-
EXECUTE TIME: 24-14-04-33:0.45384600 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Lang.php
-
EXECUTE TIME: 24-14-04-33:0.45480200 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Controller.php
-
EXECUTE TIME: 24-14-04-33:0.45933300 C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system\core\Loader.php
下面我们逐个文件进行剖析:
STEP1 index.php
该文件里面都是定义一些常量,值得注意的几个变量有:
-
$system_path = 'system';
-
$application_folder = 'application';
-
define('APPPATH', $application_folder.'/');
-
$system_path = realpath($system_path).'/';
-
realpath() 函数返回绝对路径,也就是返回了system的绝对路径,接着判断上述两个路径是否真实,有效。
-
这里还定义了basepath:
-
define('BASEPATH', str_replace("\\", "/", $system_path))
-
require_once BASEPATH.'core/CodeIgniter.php';
接着我们就看了
\system\core\CodeIgniter.php的提示信息
这个文件是CI的核心文件,它的主要用途是系统初始化以及加载类以及处理用户请求,我们一一分析
STEP2 CodeIgniter.php ----该文件首先还是定义一些版本信息,然后加载函数类Common.php,这个类很重要,后面的讲述都依靠该通用函数,我们逐一分析
------require(BASEPATH.'core/Common.php'); 即system/core/common.php,和我们的流程图一致。
这里定义的函数都是全局函数,在定义一个函数之前,首先需要确定该函数是否存在,类似C中的宏,
function_exists,判断函数是否存在,如不存在,则定义个新的函数,这里引入一个新的问题,php里面定义的函数在哪里查看?
-
$i = 0;
-
$funset=get_defined_functions();
-
//print_r($funset);
-
//$inter=$funset['internal'];
-
$inter=$funset['user'];
-
// print_r($inter);
-
$total=count($inter);
-
for (;$i<$total;$i++)
-
echo 'NO'.$i."is :".$inter[$i]."\r\n";
php里面用户定义的函数是有内部函数和用户自定义函数构成的关联数组,感兴趣的筒子自己打印。
function is_php 用来判断php版本是否满足CI的版本需求
function is_really_writable 判断文件是否可写
function &load_class 进行class的注册和实例化,并返回该类的实例引用,同时将已注册类的信息记录到变量$_is_loaded中。在加载类的时候,搜索顺序是应用库,系统库。该函数 除了加载类并实例化以后,还可以加载 class extension,这里又引用了config_item
function config_item($item),返回特定的配置项
function &get_config 加载配置类文件,即使配置文件本身不存在,同时配置文件里面的配置信息可能会被覆盖,最终返回的结果是$_config
load_class 首先加载应用类库,然后加载用户的自己定义扩展类库,这里你可以编写自定义的类来覆盖系统自带的类库
-
require($path.$directory.'/'.$class.'.php');
-
require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
function show_error 异常及错误处理
function show_404 404 的异常处理
function log_message 记录日志信息
function set_status_header 设置HTTP 报头
function _exception_handler 异常处理类
function remove_invisible_characters 主要用来异常字符
function html_escape HTML转移字符
在加载完common.php后,接着加载CI框架常量,该文件里面定义了文件及目录模式,以及文件操作模式
点击(此处)折叠或打开
-
if (isset($assign_to_config['subclass_prefix']) AND $assign_to_config['subclass_prefix'] != '')
-
{
-
get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
-
}
确定CI类的base类是否被扩展,通过subclass_prefix来确定
$BM =& load_class('Benchmark', 'core'); 加载benchmark类
$EXT =& load_class('Hooks', 'core'); 实例化hook class,
这里直接调用了hook,然后进行实例化,hook主要用来扩张CI框架,在不影响系统的前提下。
var $enabled = FALSE; 确定是否启用hooks
var $hooks = array(); 开启所有hooks
该类的实例化比较简单,比较重要的方法有2个:
function _call_hook 调用hooks,第一次调用$this->_run_hook($this->hooks[$which]);
function _run_hook 真正执行hooks
$EXT->_call_hook('pre_system');可知hooks并没有这真正的执行
下面接着实例化很多类如:CONFIG,UTF8,URI,ROUTER,OUTPUT,SECURITY,INPUT,LANG,
实例化router的时候,核心controller还执行了RTR->_set_routing();
该函数设置默认的路由规则
如查询字符串是否在配置文件,通常CI不使用query string,因为uri 段对搜索引擎很有好的,
这两种的区别:
segment based URLs:example.com/who/what/where/
query string based URLs: example.com?who=me&what=something&where=here
-
// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
// since URI segments are more search-engine friendly, but they can optionally be used.
// If this feature is enabled, we will gather the directory/class/method a little differently
默认没有启用,而后加载了route的配置文件:
include(APPPATH.'config/routes.php');
内容如下;
-
$route['default_controller'] = "welcome";
-
$route['404_override'] = '';
接着获得Uri:
-
$this->uri->_fetch_uri_string();
uri 类首先根据配置文件定义的传输协议,自动探测uri,如果不是命令行,则自动调用
点击(此处)折叠或打开
-
$this->_detect_uri
-
$uri = $_SERVER['REQUEST_URI'];
这里需要注意到Apache 2.2 对request的封装,input类进行处理后,uri进行解析:$_server里面包含很多信息
input类里面值得注意的一个方法是:$this->_sanitize_globals();清理不受保护的变量
接着contrrolleR类,require BASEPATH.'core/Controller.php';
return CI_Controller::get_instance();返回担单态类实例
该类及其简单:
-
foreach (is_loaded() as $var => $class)
-
{
-
$this->$var =& load_class($class);
-
}
将上述已经实例化的类的引用赋值给controller,接着加载了loader class,并初始化,将上述流程图中的最后一个加载类
-
$this->load =& load_class('Loader', 'core');
-
$this->load->initialize();
我们还是接着看controller,从上面的流程图以及上述分析可以看出到此,所有需要的类都被加载并被保存到
CI_Controller中
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
fetch_directory() 请求controller类文件目录;
fetch_class() 请求的controller 类名
接着处理一个单独请求,并实例化请求类
批量修改文件的脚本如下:
-
# add one tips to CI php file
-
import os
-
curdir=r"C:\Users\kinfinger\Desktop\CodeIgniter_2.2.0\CodeIgniter_2.2.0\system";
-
for root,dirs,fileset in os.walk(curdir):
-
#print root+'-----------------------Root\r\n'
-
#print "+++".join(dirs)+'\r\n'
-
#print fileset
-
for eachfile in fileset:
-
xx,ext=os.path.splitext(eachfile)
-
if (ext == '.php'):
-
curfile=os.path.join(root,eachfile)
-
print 'BEGIN OF PROCESSING :'+curfile+"\n"
-
filehandle=open(curfile,"r")
-
totallines=filehandle.readlines();
-
filehandle.close()
-
i=1
-
newfile=open(curfile,"w") # TRUNCATE THE FILE
-
for line in totallines:
-
if (i== 1):
-
newfile.writelines(line)
-
newfile.writelines('list($msec,$sec)=explode(" ",microtime());\n')
-
newfile.writelines('echo "EXECUTE TIME: ".date("d-H-i-s").":".$msec.')
-
newfile.writelines( '" ".__FILE__."
";\n')
-
else:
-
newfile.writelines(line)
-
i=i+1
-
newfile.close()
-
print "END OF PROCESSING :"+curfile+"\n"
阅读(2181) | 评论(0) | 转发(0) |