一步一步重写 CodeIgniter 框架 (10) —— 使用 CodeIgniter 类库(续)
上一节简单实现了 CI 的类库扩展模型,所以 _ci_load_class 和 _ci_init_class 写的不是很完备。根据上节课的分析,当 system/libraries 目录下存在 Email.php, 然后在 application/libraies 目录下存在 My_Email.php 时就可以实现扩展类库的功能。除了扩展之外,我们还需要:
1)直接覆盖原始类
2)完全自定义类
很简单,按照约定,当不存在MY_开头的类库文件,加载类库的情况必定属于以上两种,如下所示
// 直接加载代码
$is_duplicate = FALSE;
foreach ($this->_ci_library_paths as $path) {
$filepath = $path.'libraries/'.$subdir.$class.'.php'; if ( ! file_exists($filepath)) {
continue;
} if (in_array($filepath, $this->_ci_loaded_files)) { if ( ! is_null($object_name)) {
$CI =& get_instance();
if ( ! isset($CI->$object_name)) {
return $this->_ci_init_class($class, '', $params, $object_name);
}
} $is_duplicate = TRUE;
log_message('debug', $class." class already loaded. Second attempt ignored.");
return;
} include_once($filepath);
$this->_ci_loaded_files[] = $filepath;
return $this->_ci_init_class($class, '', $params, $object_name);
}
其中 _ci_libraries_path 在初始构造函数中初始化如下:
$this->_ci_library_paths = array(APPPATH, BASEPATH);
注意顺序,先是 APPPATH, 然后再是 BASEPATH, 保证加载的顺序先是 application ,再是 system。
再来看一下 _ci_init_class 函数
public function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL) {
if ($prefix == '') {
if (class_exists('CI_'.$class)) {
$name = 'CI_'.$class;
} elseif (class_exists(config_item('subclass_prefix').$class)) {
$name = config_item('subclass_prefix');
} else {
$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);
// 这里对名字做了一个特殊的映射,针对 unit_test 就可以直接用 unit, 而非 unit_test
if (is_null($object_name)) {
$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
} else {
$classvar = $object_name;
}
// 保存 class 名和对象名, 以供判断某个类库是否加载
$this->_ci_classes[$class] = $classvar;
$CI =& get_instance();
if ($config !== NULL) {
$CI->$classvar = new $name($config);
} else {
$CI->$classvar = new $name;
}
分析以上代码可以发现,为了直接覆盖原始的类库文件,对 $prefix ==‘’ 的情况作了进一步处理,判断是否存在 CI 或自定义MY_前缀的类,从而保证获得正确的类名。
实例名也考虑到了一种特殊的情况,比如加载 unit_test 类的时候,直接使用 unit 作为变量,这也值得我们借鉴和考虑!!!也就是说,在考虑到一般的情况下,还可以做更灵活的处理,对类名较长的类直接通过配置的方式指定实例名,非常简洁~
总结: 整个过程加载类库的设计就完成了,特别灵活和方便。
一步一步重写 CodeIgniter 框架 (10) —— 使用 CodeIgniter 类库(续)的更多相关文章
- 一步一步重写 CodeIgniter 框架 (9) —— 使用 CodeIgniter 类库
通过前面几节的内容,我们从零开始搭建了一个非常方便的MVC框架,理解了 CodeIgniter 框架最核心的部分.然而一个框架的便利不仅仅在于提供一个MVC就可以了,它还必须具有较高的扩展性.下面将从 ...
- 一步一步重写 CodeIgniter 框架 (11) —— 使用 CodeIgniter 函数库
在完成了CI框架的类库扩展后,很自然我们就会想到函数库的扩展.函数库的扩展在 CI 中称为 helper 函数与类有不同的地方,它不能继承,只能覆盖或者添加新的函数,或者直接完全新定义的一组函数. 由 ...
- **【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 中的'分段', 映射到某个类的某个方法,从而由该方法来输出最终显示的页面内容.那么我们第一课中就是实现一个这样的原 ...
随机推荐
- Spring Cache使用详解
Spring Cache Spring Cache使用方法与Spring对事务管理的配置相似.Spring Cache的核心就是对某个方法进行缓存,其实质就是缓存该方法的返回结果,并把方法参数和结果用 ...
- HDU 2227 Find the nondecreasing subsequences
题目大意:给定一个序列,求出其所有的上升子序列. 题解:一开始我以为是动态规划,后来发现离散后树状数组很好做,首先,c保存的是第i位上升子系列有几个,那么树状数组的sum就直接是现在的答案了,不过更新 ...
- 【LeetCode】Flatten Binary Tree to Linked List
随笔一记,留做重温! Flatten Binary Tree to Linked List Given a binary tree, flatten it to a linked list in-pl ...
- 2014年去哪儿网笔试题--有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来。
有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来. 这两个文件内容如下: context.txt “并不是每个人都需要$(qunar)自己的粮食,$(f ...
- N bulbs(规律)
N bulbs Accepts: 408 Submissions: 1224 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 655 ...
- C++模板编程
如何处理函数模板中的函数体? 预备知识补充: 按照c++的语言系统,普通函数及类的声明应该放在一个头文件中(通常是.h. .hpp..hh为扩展名)里: 而将其实现放在一个主代码文件中(通常以.c . ...
- js 特效 手风琴效果
$(document).ready(function(){ //定义展开的块 var lastBlock = $('#a1'); //展开的块的宽度 var maxWidth = 406; //折叠的 ...
- Mybatis 逆向工程
Mybatis逆向工程: 推荐用Java和XML Configuration的方式生成逆向文件 Java类: package generation; import java.io.File; impo ...
- Cannot mix incompatible Qt library (version 0x40801) with this library (version 0x40804)
安装EMAN2(单颗粒重构的软件)之后,运行e2projectmanager.py来启动程序出现了这个错误. 去网上找了一下,发现一个靠谱的方案,这个问题出现是由于EMAN2这个程序自带了Qt的库,而 ...
- jquery选择器控制Html元素
1.JQuery中有addClass,removeClass,toggleClass addClass(class):为每个匹配的元素添加指定的类名 removeClass(class):从所有匹配的 ...