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里的类库,分别是:
  1. {
  2. benchmark: "Benchmark",
  3. hooks: "Hooks",
  4. config: "Config",
  5. log: "Log",
  6. utf8: "Utf8",
  7. uri: "URI",
  8. router: "Router",
  9. output: "Output",
  10. security: "Security",
  11. input: "Input",
  12. lang: "Lang",
  13. loader: "Loader"
  14. }

每个类库的注释在上图已有解释。

     同时也加载 应用项目 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() 函数:
  1. /**
  2. * Helper Loader
  3. *
  4. * @param string|string[] $helpers Helper name(s)
  5. * @return object
  6. */
  7. public function helper($helpers = array())
  8. {
  9. is_array($helpers) OR $helpers = array($helpers);
  10. foreach ($helpers as &$helper)
  11. {
  12. $filename = basename($helper);
  13. $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename));
  14. $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper';
  15. $helper = $filepath.$filename;
  16.  
  17. if (isset($this->_ci_helpers[$helper]))
  18. {
  19. continue;
  20. }
  21.  
  22. // Is this a helper extension request?
  23. $ext_helper = config_item('subclass_prefix').$filename;
  24. $ext_loaded = FALSE;
  25. foreach ($this->_ci_helper_paths as $path)
  26. {
  27. if (file_exists($path.'helpers/'.$ext_helper.'.php'))
  28. {
  29. include_once($path.'helpers/'.$ext_helper.'.php');
  30. $ext_loaded = TRUE;
  31. }
  32. }
  33.  
  34. // If we have loaded extensions - check if the base one is here
  35. if ($ext_loaded === TRUE)
  36. {
  37. $base_helper = BASEPATH.'helpers/'.$helper.'.php';
  38. if ( ! file_exists($base_helper))
  39. {
  40. show_error('Unable to load the requested file: helpers/'.$helper.'.php');
  41. }
  42.  
  43. include_once($base_helper);
  44. $this->_ci_helpers[$helper] = TRUE;
  45. log_message('info', 'Helper loaded: '.$helper);
  46. continue;
  47. }
  48.  
  49. // No extensions found ... try loading regular helpers and/or overrides
  50. foreach ($this->_ci_helper_paths as $path)
  51. {
  52. if (file_exists($path.'helpers/'.$helper.'.php'))
  53. {
  54. include_once($path.'helpers/'.$helper.'.php');
  55.  
  56. $this->_ci_helpers[$helper] = TRUE;
  57. log_message('info', 'Helper loaded: '.$helper);
  58. break;
  59. }
  60. }
  61.  
  62. // unable to load the helper
  63. if ( ! isset($this->_ci_helpers[$helper]))
  64. {
  65. show_error('Unable to load the requested file: helpers/'.$helper.'.php');
  66. }
  67. }
  68.  
  69. return $this;
  70. }
     这段代码主要是 加载(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 文件下配置你链接的参数:
  1. $db['default'] = array(
  2. 'dsn' => '',
  3. 'hostname' => 'localhost',
  4. 'username' => '',
  5. 'password' => '',
  6. 'database' => '',
  7. 'dbdriver' => 'mysqli',
  8. 'dbprefix' => '',
  9. 'pconnect' => FALSE,
  10. 'db_debug' => (ENVIRONMENT !== 'production'),
  11. 'cache_on' => FALSE,
  12. 'cachedir' => '',
  13. 'char_set' => 'utf8',
  14. 'dbcollat' => 'utf8_general_ci',
  15. 'swap_pre' => '',
  16. 'encrypt' => FALSE,
  17. 'compress' => FALSE,
  18. 'stricton' => FALSE,
  19. 'failover' => array(),
  20. 'save_queries' => TRUE
  21. );
然后在 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 SQL QUERY...');$this->db->query('ANOTHER QUERY...');$this->db->query('AND YET ANOTHER QUERY...');$this->db->trans_complete();
 

提供了简单的查询缓存:

将查询结果对象会被序列化并保存到服务器上的一个文本文件中。 当下次再访问该页面时,会直接使用缓存文件而不用访问数据库了。只有读类型(SELECT)的查询可以被缓存。 这个相对应 Java 的hibernate 数据库映射 就弱化了很多,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');
 
最后输出分析的信息:
$sections=array('config'=>TRUE,'queries'=>TRUE);
$this->output->set_profiler_sections($sections);
 
下表列出了可用的分析器字段和用来访问这些字段的 key :
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  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
以上是我对CI框架大致的了解与分析,我做php的经验不多,这是我第一个尝试去深入了解的php框架,请大家多多指教。
转载来自:https://www.cnblogs.com/xiaoxiaoqingyi/p/6901654.html

CI框架浅析的更多相关文章

  1. CI框架浅析(二)

    该文延续上篇文章: CI框架浅析(一) 在CI框架的核心库中,CodeIgniter.php负责加载所有需要的类库,第一个加载的是公共库 core/Common.php Common.php 负责加载 ...

  2. CI框架浅析(全篇)

        业余花了点时间看看CodeIgniter框架(简称CI),CI目前的稳定版本是 3.X,4.0版本已经出来了,但还在测试中,所以我分析的还是 3.x 版本. CI是一个很轻便的框架,整个下载包 ...

  3. CI框架浅析(一)

            CodeIgniter 是一个小巧但功能强大的 PHP 框架,作为一个简单而“优雅”的工具包,它可以为开发者们建立功能完善的 Web 应用程序.本人使用CI框架有一段时间了,现在决定把 ...

  4. ci框架登陆之后每隔几分钟就需要重新登录的问题

    一个简单的登陆写好之后,发现每次进入需要登陆之后才能进入的页面都会跳转到登录页面,猜测应该是session被清了,打印出来,果然为空,但是我没有设置session的生存周期,按照默认的应该是24小时, ...

  5. 第一天ci框架开发商城2

    ci框架开发商城2 1/28/2016 9:45:52 PM mvc完整案例 mvc完成新闻的增删改查 news控制器news.php class News extends CI_controller ...

  6. 第一天ci框架开发商城1

    ci框架开发商城1 1/28/2016 9:43:52 PM userguide删除 system application controllers 控制器 models 模型 views 视图 模板 ...

  7. CI框架之HOOKS使用流程及原理

        Ci框架中Hooks可以理解:在框架的执行流程过程中,允许开发者在固定的某些时间点上(如:调用控制器前,调用控制器后等时间点上),调用其他函数来扩充CI框架执行流程的一种方法.技术上来就是通过 ...

  8. CI框架使用PHPmail插件发送QQ邮件:

    有助请顶,不好请评.0:33 2016/3/12CI框架使用PHPmail插件发送QQ邮件:发送成功,不过修改了主机参数,还包含了一个phpmail中的一个另外的文件,详见下方:参见:http://c ...

  9. 初学后台框架总结篇二——快速了解CI框架

    一.下载CI框架并安装,这里放置一张自己的项目目录结构图 目录框架搭建好之后开始将自己的项目与框架融合 二.更改相关配置 1.用任何文本编辑器打开 application/config/config. ...

随机推荐

  1. 【Leetcode】605. Can Place Flowers

    Description Suppose you have a long flowerbed in which some of the plots are planted and some are no ...

  2. Tensorflow的最佳实践

    Tensorflow的最佳实践 1.变量管理   Tensorflow提供了变量管理机制,可直接通过变量的名字获取变量,无需通过传参数传递数据.方式如下: #以下为两种创建变量的方法 v=tf.get ...

  3. java 获取图片大小(尺寸)

    1,获取本地图片大小(尺寸) File picture=new File(strSrc);BufferedImage sourceImg=ImageIO.read(new FileInputStrea ...

  4. python2.7入门---file(文件)&OS 文件&目录方法

        首先file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数: 序号 方法及描述 1 file.close() 关闭文件.关闭后文件不能再进行读写操作. 2 file.f ...

  5. vue2.0 Axios 的简单用法

    安装 使用 npm: $ npm install axios 使用 bower: $ bower install axios 使用 cdn: <script src="https:// ...

  6. CSS3实现3D球体旋转动画

    html <div class="ball-box"> <div class="ball"> <div class="l ...

  7. 0301001_Lesson1&2

    Lesson 1 Excuse me! 对不起! Listen to the tape then answer this question.Whose handbag is it?听录音,然后回答问题 ...

  8. 【数据库】 SQL 通配符

    [数据库] SQL 通配符 1. % : 替代一个或多个字符 2. _ : 仅替代一个字符 3. [] : 字符列中的任何单一字符 4. [^charlist] 或者 [!charlist]  : 不 ...

  9. 13.0 Excel表格写入

    Excel表格写入 安装 xlutils 和 xlwt Excel写入输入 分两种方式: 第一种是向一张新表之中写入..这种不多说,我几乎没怎么用,直接贴代码 import xlwt Excel_na ...

  10. redux使用过程中遇到的两个致命的关键点

    一.在reducer中,返回的state必须是全新的对象,否则,redux不会执行listening方法,因为redux会认为state没有更新过,没必要重新渲染view. 出现问题的例子: cons ...