一步一步重写 CodeIgniter 框架 (9) —— 使用 CodeIgniter 类库
通过前面几节的内容,我们从零开始搭建了一个非常方便的MVC框架,理解了 CodeIgniter 框架最核心的部分。然而一个框架的便利不仅仅在于提供一个MVC就可以了,它还必须具有较高的扩展性。下面将从 CodeIgniter 的官方文档中的顺序一步一步充实我们这个“丑陋” 的框架。
本课将实现 CodeIgniter 类库加载的模式,对应于http://codeigniter.org.cn/user_guide/general/libraries.html
1. library 函数
首先类库加载设计在 Loader 类中,函数命名为 library,如下所示
public function library($library = '', $params = NULL, $object_name = NULL) {
if (is_array($library)) {
foreach ($library as $class) {
$this->library($class, $params);
}
return;
}
if ($library == '' OR isset($this->_base_classes[$library])) {
return FALSE;
}
if ( ! is_null($params) && ! is_array($params)) {
$params = NULL;
}
$this->_ci_load_class($library, $params, $object_name);
}
与 model 类似,它首先判断传入的第一个参数是否为数组,如果是的话,就递归调用一次。
它通过调用 _ci_load_class 函数来实际加载具体的类。
2. _ci_load_class 函数实际加载
protected function _ci_load_class($class, $params = NULL, $object_name = NULL) {
$class = str_replace('.php', '', trim($class, '/'));
$subdir = '';
if (($last_slash = strrpos($class, '/')) !== FALSE) {
// 提取出路径
$subdir = substr($class, 0, $last_slash + 1);
// 提取出 class
$class = substr($class, $last_slash + 1);
}
foreach (array(ucfirst($class), strtolower($class)) as $class) {
$subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php';
// class 扩展
if (file_exists($subclass)) {
$baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php';
if ( ! file_exists($baseclass)) {
log_message('error', 'Unable to load the requested class: '.$class);
show_error('Unable to load the requested class: '.$class);
}
// 检查 class 是否加载过
if (in_array($subclass, $this->_ci_loaded_files)) {
if (! is_null($object_name)) {
$CI =& get_instance();
if ( ! isset($CI->$object_name)) {
return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
}
}
$is_duplicate = TRUE;
log_message('debug', $class." class already loaded. Second attempt ignored.");
return;
}
include_once($baseclass);
include_once($subclass);
$this->_ci_loaded_files[] = $subclass;
return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
}
}
if ($is_duplicate == FALSE) {
log_message('error', 'Unable to load the requested class: '.$class);
show_error("Unable to load the requested class: ".$class);
}
}
按照 CodeIgniter 的思路,首先会对加载函数的第一个参数路径进行拆分,得到具体的路径和文件名,因为文件名会有一些特殊的约定。
CodeIgniter 在设计的时候有个很重要的思想,就是区分 system 和 application 两种类型的代码,从而设计出灵活性很高的框架,那么针对 类库 而言,就是在 system 中提供一些常用的类库,然后给用户在这个基础上扩展或覆盖的权利,另外,也可以直接在
application 文件夹下设计出完全自定义的类。
本节主要实现 在原有类上进行扩展 的代码
1) 首先判断 application 文件夹下是否存在按照约定命名的扩展类库文件,即 subclass_prefix = 'MY_', 就判断是否存在 MY_类库名.php 文件
2)如果存在,则加载基类库文件,全部 include 之后,就可以 _ci_init_class 了
3. _ci_init_class 实例化 class
public function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL) {
if ($prefix == '') {
$name = $class;
} else {
$name = $prefix.$class;
}
if ( ! class_exists($name)) {
log_message('error', "Non-existent class: ".$name);
show_error("Non-existent class: ".$class);
}
$class = strtolower($class);
$classvar = $class;
$CI =& get_instance();
if ($config !== NULL) {
$CI->$classvar = new $name($config);
} else {
$CI->$classvar = new $name;
}
}
然后通过
$CI->$classvar = new $name($config); 成为 CI 核心对象的成员,从而就可以很方便的访问了~ $this->email->函数名();
一步一步重写 CodeIgniter 框架 (9) —— 使用 CodeIgniter 类库的更多相关文章
- 一步一步重写 CodeIgniter 框架 (11) —— 使用 CodeIgniter 函数库
在完成了CI框架的类库扩展后,很自然我们就会想到函数库的扩展.函数库的扩展在 CI 中称为 helper 函数与类有不同的地方,它不能继承,只能覆盖或者添加新的函数,或者直接完全新定义的一组函数. 由 ...
- 一步一步重写 CodeIgniter 框架 (10) —— 使用 CodeIgniter 类库(续)
上一节简单实现了 CI 的类库扩展模型,所以 _ci_load_class 和 _ci_init_class 写的不是很完备.根据上节课的分析,当 system/libraries 目录下存在 Ema ...
- **【ci框架】精通CodeIgniter框架
http://blog.csdn.net/yanhui_wei/article/details/25803945 一.大纲 1.codeigniter框架的授课内容安排 2.codeigniter框架 ...
- CodeIgniter框架——知识要点汇总
NO1.学习要点: 一.CodeIgniter 框架的简介 二.CodeIgniter 框架的安装 三.CodeIgniter 框架的目录结构分析 四.CodeIgniter 框架是如何工作的? 五. ...
- 一步一步重写 CodeIgniter 框架 (6) —— 实现在控制器Controller中加载View
1. 控制器将模型类获得的数据,传递给视图进行显示,所以视图必须负责接收数据,另外重要的一点是当模型和视图分开后,多个模型的数据可以传递给一个视图进行展示,也可以说一个模型的数据在多个不同的视图中进行 ...
- 一步一步重写 CodeIgniter 框架 (5) —— 实现Controller,并加载Model
CodeIgniter 框架采用MVC模式,而MVC模式中起纽带作用的就是C(控制器),在控制器的中通过加载模型获得数据,将数据传到视图中进行展示.本课将实现在控制器中加载模型. 1. 控制器的实现 ...
- 一步一步重写 CodeIgniter 框架 (4) —— load_class 管理多个对象实例的思路
我们使用CodeIgniter 框架最主要是想利用其 MVC 特性,将模型.视图分开,并通过控制器进行统一控制.在尝试实现 MVC 模式之前,我们将实现其中一个对程序结构非常有用的技巧,就是 load ...
- 一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码
前面两篇文章为了重点突出 CodeIgniter 框架的原理,程序的结构很乱,有很多全局变量,在这一课中我们采用面向对象的方法对原先代码进行重构. 到目前为止,程序主要完成的就是 URL 分析,并根据 ...
- 一步一步重写 CodeIgniter 框架 (1) —— url 如何映射到具体的方法
CodeIgniter 框架最显著的特征就是 MVC 模式,它的做法就是提取 url 中的'分段', 映射到某个类的某个方法,从而由该方法来输出最终显示的页面内容.那么我们第一课中就是实现一个这样的原 ...
随机推荐
- 求最大值最小值的方法 时间复杂度O(n)
#include<iostream> #include <iostream> #include <bitset> #include <ctime> us ...
- JAVA中SSH面试问题
1.阐述struts2的执行流程. Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher.业务控制器Action和用户实现的企业业务逻辑组件.核心控制器Filter ...
- Romantic(裸扩展欧几里德)
Romantic Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- [cocos2d-x]用CCSpriteBatchNode进行文理贴图的优化
引言: 我们在进行手机游戏开发的过程中,由于手机的内存资源是有限的,那么对纹理贴图的优化是非常有必要的,有可能相同的功能,优化的好与不好对内存资源的消耗是非常明显的,下面我就用一个例子来说明一下. 说 ...
- RGB与HSB之间的转换公式
先来了解一些概念: 1.RGB是一种加色模型,就是将不同比例的Red/Green/Blue混合在一起得到新颜色.通常RGB颜色模型表示为: 2.HSB(HSV) 通过色相/饱和度/亮度三要素来表达颜色 ...
- PHP程序猿必须学习的第二课——站点安全问题预防
作为PHP程序猿.第一课我们学习了基本的语法.那么在熟悉基本的语法之后我们应该学些什么呢?我觉得是安全问题.安全问题基于一个站点宛如基石,一着不慎,意味着灾难性的事故. 这里主要就提三点最简单,也是最 ...
- ELF文件数据布局探索(1)
作为一名Linux小白,第一次看到a.out这个名字,感觉实在是奇怪,搜了一下才知道这是编译器输出的默认可执行文件名 然后vi一下,哇,各种乱码,仔细看看,发现了三个清晰的字符ELF.继续搜索, 第一 ...
- 部署django - Apache + mod_wsgi + windows
部署django - Apache + mod_wsgi + windows 1.环境 django 1.6.2 python 3.3 32位 apache 2.4.7 32位 一个可以使用的djan ...
- Code one 码
Code one是一种用成像设备识别的矩阵式二维条码.Code one符号中包含可由快速性线性探测器识别的识别图案.每一模块的宽和高的尺寸为X. Code one符号共有10种版本及时14种尺寸.最 ...
- Qt之OpenSSL(有pro文件的路径格式)
简述 OpenSSL是一个强大的安全套接字层密码库,囊括主要的密码算法.常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用. 简述 下载安装 使用 更多参考 下载安装 ...