CodeIgniter 源码分析第一弹

来源:互联网 发布:手机影视制作软件 编辑:程序博客网 时间:2024/05/19 00:48

CodeIgniter 2.13 运行过程

index.php 系统环境配置,公共变量定义

  |__CodeIgniter.php  

  |__开始时就包含 Common.php

  |__包含静态配置文件 Constants.php

  >通过Load_class方法,加载如下核心类:

             | Benchmark $BM  

  >1.记录系统运行起始点 2.记录加载文件起始点

       | Hooks $EXT

             | Config $CFG

  >加载自定义配置内容

             | Utf8 $UNI

   | URI $URI

   | Router   $RTR

  >初始化路由

  | Output $OUT 

>判断是否存在可用缓存,如果有显示缓存文件

      | Security $SEC

   | Input $IN

  | Lang $LANG

  |__包含core/Controller.php 

  |__包含应用程序中core/[前缀]Controller.php 如果有的话,

  |______包含URL请求的Controller文件,默认welcome(可定义)。先判断是否有这个文件,没有报错

  >记录加载基本类类文件结束点

      >$RTR获取 

  |>$RTR->fetch_class获取控制器名

  |>$RTR->fetch_method获取方法名

  类名和方法名->判断是否存在该类名,不存在的话报404错误(CI提供了两种404报错方案)

  >调用Hook pre_controller

  >记录控制器运行起始点

      >实例化控制器类

  foreach (is_loaded() as $var => $class)  {

  $this->$var =& load_class($class);

  }

  》将已经记载的类包含到类中,这个代码很赞

  >实例化Loader类 很重要的一个类,各种类库,helper都是通过它来加载实现的

  >判断是否存在方法名,不存在的话报404,存在的话使用系统函数call_user_func_array调用并执行该方法

       >记录控制器运行结束点

       >调用Hook post_controller

  >判断Hook display_override 是否false,是则显示结果

       >调用Hook post_system

               >判断是否产生数据库对象,如果存在关闭数据库对象连接

 

Benchmark类分析

用于记录点之间的时间差,和计算内存使用量

mark()函数,添加记录点。时间点存储在属性marker里。

$this->marker[$name] = microtime(); 

elapsed_time()函数,计算记录点之间的时间差

{elapsed_time} 可在模板中自由使用

memory_usage()函数,计算内存使用率

{memory_usage} 可在模板中自由使用

Hook类分析

功能是使得我们可以在不修改系统核心文件的基础上来改变或增加系统的核心运行功能。

启用钩子

钩子功能可以在全局范围内打开或关闭,您可以在 application/config/config.php 文件中设定:

$config['enable_hooks'] = TRUE;

定义钩子

钩子是在 application/config/hooks.php 文件中定义的。 每个钩子可以用以下格式的数组来定义:

$hook['pre_controller'] = array(
                                'class'    => 'MyClass',
                                'function' => 'Myfunction',
                                'filename' => 'Myclass.php',
                                'filepath' => 'hooks',
                                'params'   => array('beer', 'wine', 'snacks')
                                );

说明:
数组的索引与你使用的指定挂钩点名字相关.上面的例子中挂钩点是pre_controller. 挂钩点参数列表如下所示. 以下各项将定义在你的相关钩子数组里:

· class  你希望调用的类名.如果你更喜欢使用过程函数代替类的话,此项保留为空.

· function  你希望调用的函数名.

· filename  包含有你的类/函数的文件名.

· filepath  包含你的脚本的目录名. 注意: 你的脚本放在 application 文件夹下的目录里, 这样 filepath就以那个文件夹(application)为基准. 例如, 如果你的脚本放在application/hooks下, 你可以把hooks 作为你的filepath. 如果你的脚本放在application/hooks/utilities下你可以把 hooks/utilities作为filepath. 注意后面没有"/".如果不放在根目录下可以根据相对路径的配置,来完成调用。这样就可以完成,多个应用共享一个钩子。

· params  你希望传递给脚本的任何参数. 此项是可选的.

上面配置的内容是我直接从文档中COPY出来的。

Hook类初始化时,包含hook.php配置文件,就是一个数组

_call_hook()函数

调用hook的函数,判断hook是否存在,是否有多个hook需要运行

_run_hook$data)函数

执行hook的函数,$data的具体内容参看配置

 

if ( ! class_exists($class))

{

require($filepath);

}

 

$HOOK = new $class;

$HOOK->$function($params);

 

疑问:数据怎么才能够传递到$Hook中进行处理

Config 类分析

load()函数 加载配置文件

item$item)函数 获取配置项内容

set_item()函数 设置更改配置项的内容,并不改配置文件里的内容

其他几个函数暂不多说,它们获取系统常用URL的方法

UTF8类分析

用于将文件转换为UTF8编码,应该很少被用到

URI类分析

解析URL地址的内容

暂不具体分析

Router分析

路由类

_set_routing() 设置路由映射。主要路由映射就是通过这个方法,再传会URI对象。

_set_request($segments = array()) 设置请求 $segments URI segments

_validate_request()验证请求的控制器是否存在

_set_overrides($routing) 设置重定向的内容 ,$routing 数组

Output类分析

final_output属性是输出前的数据

$this->output->set_output($data); 重要:使用这个方法一定将它放在最后一句。

get_out() 可以得到将要输出的数据,并把它保存起来,留着它可用于生成静态HTML文件

append_output($data) 附加数据

cache()函数  设置缓存的时间

_write_cache$output) 写缓存到$cache_path = ($path == '') ? APPPATH.'cache/' : $path;  fwrite($fp, $expire.'TS--->'.$output); 截取的部分代码

_display_cache()显示缓存 CI使用$cache = fread($fp, filesize($filepath));读取缓存内容

_display()函数  最终输出数据到客户浏览器

Security类分析

安全类暂不作分析

Input类分析

输入类有两个目的:

· 为了安全,预处理输入数据。

· 提供helper的一些方法,取得输入数据,并预处理输入数据。

安全过滤(Security Filtering)

当触发一个控制器的时候,安全过滤(Security Filtering)功能自动启动。做以下事情:

· If $config['allow_get_array'] is FALSE(default is TRUE), destroys the global GET array.

· 当 register_globals 被设置为 on 的时候,销毁所有的全局变量。

· 过滤 GET/POST/COOKIE 数组键,只允许字母-数字(以及一些其它的)字符。

· 可以过滤跨站脚本攻击 (Cross-site Scripting Hacks) 此功能可全局打开(enabled globally),或者按要求打开。

· 换行符统一换为 \n(Windows 下为 \r\n)

跨站脚本(XSS)过滤

输入类有能力阻止跨站脚本攻击。如果你想让过滤器遇到 POST 或者 COOKIE 数据时自动运行,你可以通过打开你的 application/config/config.php 文件进行如下设置实现:

$config['global_xss_filtering'] = TRUE;

_fetch_from_array (&$array, $index = '', $xss_clean = FALSE)主要的函数,无论是get,post,cookie,server都是通过它来运作的,根据不同的参数,返回不同个的数组,get返回$_GET里面的内容等等。参数$xss_clean用于配置是否开启跨站脚本过滤。

直接使用$this->input->get()或$this->input->post()另外一个好处是不用判断是否存在该变量。

set_cookie()用于设置一个Cookie的值

ip_address()获取当前用户的IP,无效时返回0.0.0.0

valid_ip($ip) 测试输入的IP地址是否有效,IPv4IPv6都测试

user_agent() 返回当前用户正在使用的浏览器的User agent信息

is_ajax_request 判断是否是AJAX请求

 $this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest'

is_cli_request 判断是否是Cli请求   

php_sapi_name() === 'cli'

Lang类分析

使用方法$this->lang->load('filename', 'language');

$this->lang->line('language_key');

有两个函数第一是load函数,根据filename作用加载相应的语言文件,语言文件保存的就是一个数组。第二是line函数,参数是下标名,就是通过下标名在数组中得到相应的值。(注:这里没有看到对文件路径有处理,filename还得添加一系列的路径才能找到,不然都只能放在Language\en文件中。)

 

 Load类分析

初始化时将存放类库,helpermodelview的路径地址包含进来。

is_loaded($class) 判断是否已经加载了$class

文件中有很多类似下面的代码

if (is_array($library))

{

foreach ($library as $class)

{

$this->library($class, $params);

}

return;

}

当传值是数组时,将每一个数组中的值作为参数在调用一次本身,就能够实现代码的执行。代码很赞!!

config() 的具体实现交给上面的config对象,所以加载congfig的类一定要放在加载loader类之前。

language()交给language对象实现

 

加载的原理是根据加载不同type的内容和类名,找到相应的文件并将其包含进来就实现了加载。思想很简单。只是不同类型的类可能处理方法不一样。暂时分析到这里。

 

如果有错,切勿拍砖,望请指正。<hzzbook@126.com>

0 0
原创粉丝点击