CI框架浅析(全篇)
业余花了点时间看看CodeIgniter框架(简称CI),CI⽬前的稳定版本是 3.X,4.0版本已经出来了,但还在测试中,所以我分析的还是 3.x 版本。CI是⼀个很轻便的框架,整个下载包也就2M多,⽽且使⽤起来⽅便快捷,适⽤于⼀些简单的功能开发,以及做app 接⼝。
该框架整个流程图如下:
1. index.php ⽂件作为前端控制器,初始化运⾏ CodeIgniter 所需的基本资源;
2. Router 检查 HTTP 请求,以确定如何处理该请求;
3. 如果存在缓存⽂件,将直接输出到浏览器,不⽤⾛下⾯正常的系统流程;
4. 在加载应⽤程序控制器之前,对 HTTP 请求以及任何⽤户提交的数据进⾏安全检查;
5. 控制器加载模型、核⼼类库、辅助函数以及其他所有处理请求所需的资源;
6. 最后⼀步,渲染视图并发送⾄浏览器,如果开启了缓存,视图被会先缓存起来⽤于后续的请求。
下载框架源码,解压得到如下代码结构:
主要有三个⽬录
1、application⽬录:⽤于开发者编写相应的配置以及逻辑处理,开发者只需在这个⽬录下添加⾃⼰需要的开发⽂件。
2、system⽬录:框架的系统库,⾥⾯包括核⼼库,类库,辅助类库,数据库等,这些⽂件,开发者最好不要擅⾃修改,它是整个框架的龙脉。
3、user_guide:⽤户⼿册。
接下来看看源码的请求流程:
⾸先假设有⼀个 URL 请求,⼊⼝就是 index.php,该⽂件定义了⼏个常量,应⽤的路径,以及核⼼库的路径等。
接着引⼊核⼼库system/core下的 CodeIgniter.php⽂件,该⽂件初始化核⼼库system/core⾥的类库,分别是:
{
● benchmark: "Benchmark",
● hooks: "Hooks",
● config: "Config",
● log: "Log",
● utf8: "Utf8",
● uri: "URI",
● router: "Router",
● output: "Output",
● security: "Security",
● input: "Input",
● lang: "Lang",
● loader: "Loader"
}
每个类库的注释在上图已有解释。
同时也加载应⽤项⽬ application/config⽬录下的配置⽂件(这些配置⽂件都是开发者根据⾃⼰的需要去添加与配置),
根据判断加载字符串处理库mbstring,添加错误异常预处理⽅法。在加载的同时,也把钩⼦部署到了相应位置,如果开发者定义了相应钩⼦实现⽅法,就会在相应的位置执⾏。在 CodeIgniter.php 初始化核⼼库的时候定义了五个钩⼦,分别如下:
pre_system 在系统执⾏的早期调⽤,这个时候只有基准测试类和钩⼦类被加载了,还没有执⾏到路由或其他的流程。
pre_controller 在你的控制器调⽤之前执⾏,所有的基础类都已加载,路由和安全检查也已经完成。
post_controller_constructor 在你的控制器实例化之后⽴即执⾏,控制器的任何⽅法都还尚未调⽤。
post_controller 在你的控制器完全运⾏结束时执⾏。
post_system 在最终的页⾯发送到浏览器之后、在系统的最后期被调⽤。
然后,实例化 CI_Controller 类:
function &get_instance()
{
return CI_Controller::get_instance();
}
通过路由 router 及 uri 得到请求的 controller控制器、method⽅法以及参数,执⾏该⽅法。
期间根据开发者在application/config⽬录下的配置,会加载相应的 librays 类库、 helper辅助函数及 DB 库。
如果你喜欢MVC的开发模式,也可以添加model类,然后加载 model 模型类,处理相应的业务逻辑。
最后在⾃⼰定义的controller控制器处理好的数据结果渲染在html 页⾯上,展⽰给⽤户。
下⾯看⼀下CI框架⼏个重要部分:
控制器
开发者在 application/controller ⽬录下添加⾃⼰的controller 控制器,但是每个控制器都要继承核⼼库⾥的基类 CI_Controller,它已获取到整个框架的核⼼类库对象,通过它基本可以调⽤CI框架下的核⼼⽅法。
模型
模型就是专门⽤来和数据库打交道的 PHP 类,开发者在 application/models ⽬录下定义⾃⼰的模型类,都要继承模型基类 CI_Mode。当你在控制下调⽤模型,只需要下⾯⼀⾏代码就实例化了:
$this->load->model('model_name');
辅助函数
当然开发者也可以创建⾃⼰的辅助类,⽂件存放在 application/helpers ⽬录下,调⽤的⽅式与系统
的辅助类⼀致。
$this->load 就是 Loader.php ⽂件CI_Load 类实例,我们来看看 CI_Load 类下的 helper() 函数:
/**
* Helper Loader
*
* @param    string|string[]    $helpers    Helper name(s)
* @return    object
*/
public function helper($helpers = array())
{
is_array($helpers) OR $helpers = array($helpers);
foreach ($helpers as &$helper)
{
$filename = basename($helper);
$filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename));
$filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper';
$helper  = $filepath.$filename;
if (isset($this->_ci_helpers[$helper]))
{
continue;
}
// Is this a helper extension request?
$ext_helper = config_item('subclass_prefix').$filename;
$ext_loaded = FALSE;
foreach ($this->_ci_helper_paths as$path)
{
if (file_exists($path.'helpers/'.$ext_helper.'.php'))
{
include_once($path.'helpers/'.$ext_helper.'.php');
$ext_loaded = TRUE;
}
}
// If we have loaded extensions - check if the base one is here
if ($ext_loaded === TRUE)
{
$base_helper = BASEPATH.'helpers/'.$helper.'.php';
if ( ! file_exists($base_helper))
{
show_error('Unable to load the requested file: helpers/'.$helper.'.php');
}
include_once($base_helper);
$this->_ci_helpers[$helper] = TRUE;
log_message('info', 'Helper loaded: '.$helper);
continue;
}
// No extensions found ... try loading regular helpers and/or overrides
foreach ($this->_ci_helper_paths as$path)
{
if (file_exists($path.'helpers/'.$helper.'.php'))
{
include_once($path.'helpers/'.$helper.'.php');
$this->_ci_helpers[$helper] = TRUE;
log_message('info', 'Helper loaded: '.$helper);
break;
}
}
// unable to load the helper
if ( ! isset($this->_ci_helpers[$helper]))
{
show_error('Unable to load the requested file: helpers/'.$helper.'.php');
}
}
return$this;
}
这段代码主要是加载(include_once) system/helpers 与 appliation/helpers ⽬录下的 $name_helper.php 名称⽂件,⾃定义的辅助函数⽂件需要添加前缀来与系统的辅助函数区分开。当执⾏完加载函数,就能得到 $this->name 实例,然后调⽤它⾥⾯的函数。
所有辅助函数如下:
CI 类库
所有的系统类库都位于 system/libraries/ ⽬录下,⼤多数情况下,在使⽤之前,你要先在控制器中初始化它,使⽤下⾯的⽅法:
$this->load->library('class_name');
'class_name' 是你想要调⽤的类库名称,例如,要加载表单验证类库,你可以这样做:
$this->load->library('form_validation');
⼀旦类库被载⼊,你就可以根据该类库的⽤户指南中介绍的⽅法去使⽤它了,这个类似于辅助函数。
同样拓展⾃⼰的类库也是在application/libraries ⽬录下。
⼀旦加载,你就可以使⽤⼩写字母名称来访问你的类,调⽤⽅法:
$this->someclass->some_method();
所有的类库如下:
数据库
CI框架封装了多种数据库驱动与连接⽅法,让你轻松配置就能连接上,且封装了⼀些查询构造器与⽣成查询结果,让代码看起来⽅便简洁。
你只需在application/config/database.php ⽂件下配置你链接的参数:
$db['default'] = array(
'dsn'    => '',
'hostname' => 'localhost',
'username' => '',
'password' => '',
'database' => '',
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',validation框架
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
)
;
然后在 Controller ⾥调⽤⼀句:$this->load->database(); 就能连接上数据库。
接着,你可以查询你想要的结果:
$this->db->where('name',$name);
$query=$this->db->get('mytable',10,20);
// Executes: SELECT * FROM mytable where name=$nameLIMIT 20, 10
CI框架也提供了数据库的事务处理,如:
$this->db->trans_start();$this->db->query('AN ');$this->db->query('');$this->db->query('AND YET ');$this->db->trans_complete();
提供了简单的查询缓存:
将查询结果对象会被序列化并保存到服务器上的⼀个⽂本⽂件中。当下次再访问该页⾯时,会直接使⽤缓存⽂件⽽不⽤访问数据库了。只有读类型(SELECT)的查询可以被缓存。这个相对应 Java 的hi
bernate 数据库映射就弱化了很多,Java提供了三级的缓存⽅式,⽽且在查询数据库的时候,并不会每次都断开,再连接。
以上都是CI框架提供的重要组成部分,也许它可能满⾜不了你所有的需求,但也提供了⼀些给你拓展的⽅式,如在application/core⽬录下添加你的核⼼类,这都是CI框架已考虑到的问题。当然它在处理⼀些繁杂的业务逻辑的时候,还是⽐较薄弱的,⽐如说权限使⽤,模块灵活增删等。
CI框架主要是以轻便,快捷上⼿为主要的优势,让你去处理⼀些简单的项⽬。它介于⼀个没有框架与⼀个⽐较笨重的框架之间,所以⼀个框架好不好⽤,还要基于你的需求。
CI框架还提供了⼀些其它便捷的开发帮助,它有有⾃⼰的模板引擎,也有程序分析:
你可以在你的控制器⽅法的任何位置添加⼀⾏下⾯的代码:
$this->output->enable_profiler(TRUE);
设置基准测试点
$this->benchmark->mark('code_start');// Some code happens here$this->benchmark->mark('code_end');echo$this->benchmark->elapsed_time('code_start','code_end');
最后输出分析的信息:
Key Description
Default benchmarks 在各个计时点花费的时间以及总时间 TRUE  config CodeIgniter 配置变量 TRUE
controller_info 被请求的控制器类和调⽤的⽅法 TRUE  get 请求中的所有 GET 数据 TRUE
http_headers
本次请求的 HTTP 头部 TRUE  memory_usage
本次请求消耗的内存(单位字节) TRUE  post
请求中的所有 POST 数据 TRUE  queries
列出所有执⾏的数据库查询,以及执⾏时间 TRUE  uri_string
本次请求的 URI TRUE  session_data 当前会话中存储的数据 TRUE
query_toggle_count 指定显⽰多少个数据库查询,剩下的则默认折叠起来25
$sections=array('config'=>TRUE,'queries'=>TRUE);
$this->output->set_profiler_sections($sections);
下表列出了可⽤的分析器字段和⽤来访问这些字段的 key :              以上是我对CI 框架⼤致的了解与分析,我做php 的经验不多,这是我第⼀个尝试去深⼊了解的php 框架,请⼤家多多指教。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。