一步一步重写 CodeIgniter 框架 (4) —— load_class 管理多个对象实例的思路
我们使用CodeIgniter 框架最主要是想利用其 MVC 特性,将模型、视图分开,并通过控制器进行统一控制。在尝试实现 MVC 模式之前,我们将实现其中一个对程序结构非常有用的技巧,就是 load_class 函数。
在上一课中,我们用面向对象的方法大大简化了程序的结构,将主要工作放在两个类中进行 ,URI 和 Router 类。 但是在 Router 类的构造函数中为了获得 uri 的实例,我们使用了 global 关键字,如下所示:
class CI_Router {
...
function __construct() {
global $URI;
$this->uri = &$URI;
}
....
}
当程序的结构变得很复杂时,用 global 关键词会使得全局变量的管理非常乱,而且这些全局变量往往对应于一个具体功能类的实例,在实例化之前需要加载相应class的 php 文件。
1. 问题提炼和分析
根据上述分析,关键的问题是
1)需要一个集成管理这些全局变量的地方
2)这些类的实例产生时,很方便的加载对应的 php 文件。
集成管理变量一般采用 类的方式,然后通过该类的一个实例(唯一一个)获取需要的变量,这个实例往往称为核心全局变量,如discuz 中的 $discuz_core 变量;
另一种方式,就是函数,但是函数没法存储成员变量,所以必须利用一个很有用的语法特性,就是 static 静态变量。
在这里,我们采用第二种更简洁的方式。
2. 实现步骤
1) 定义函数的接口
函数名为 load_class , 我们希望通过传递一个字符串参数,就能获得对应的实例,比如 load_class('Router'); 就可以得到 上一课中的 $RTR 变量的引用。
所以函数的接口为:
function &load_class($class) {}
2) 定义存储这些重要类实例全局变量的静态数组
static $_classes = array();
那么该数组,存储的键值对就是 ’Router' => $RTR 的样子。
3) 具体的逻辑
// 当加载需要的类实例时,如果不是第一次加载,那么 $_classes 数组中肯定存放了需要的实例,直接返回即可
if (isset($_classes[$class])) {
return $_classes[$class];
} // 在我们的框架中,每个类实例都有前缀CI_
$name = 'CI_'.$class; if (file_exists($class.'.php')) {
require($class.'.php');
} else {
exit('Unable to locate the class');
} $_classes[$class] = new $name();
return $_classes[$class];
3. 修改主逻辑代码
<?php
/**
* 框架主入口文件,所有的页面请求均定为到该页面,并根据 url 地址来确定调用合适的方法并显示输出
*/
require('Common.php'); $URI =& load_class('URI');
$RTR =& load_class('Router'); $RTR->set_routing(); $class = $RTR->fetch_class();
$method = $RTR->fetch_method(); $CI = new $class(); call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2)); class Welcome { function hello() {
echo 'My first Php Framework!';
} function saysomething($str) {
echo $str.", I'am the php framework you created!";
}
}
另外,所有需要用到这些全局变量的地方,调用 load_class 就可以了,所以 Router 构造函数的地方使用 load_class.
function __construct() {
$this->uri =& load_class('URI');
}
4. 测试结果
访问 http://localhost/learn-ci/index.php/welcome/hello , 可以看到输出为:
hello, I'am the php framework you created!
一步一步重写 CodeIgniter 框架 (4) —— load_class 管理多个对象实例的思路的更多相关文章
- 一步一步重写 CodeIgniter 框架 (9) —— 使用 CodeIgniter 类库
通过前面几节的内容,我们从零开始搭建了一个非常方便的MVC框架,理解了 CodeIgniter 框架最核心的部分.然而一个框架的便利不仅仅在于提供一个MVC就可以了,它还必须具有较高的扩展性.下面将从 ...
- 一步一步重写 CodeIgniter 框架 (6) —— 实现在控制器Controller中加载View
1. 控制器将模型类获得的数据,传递给视图进行显示,所以视图必须负责接收数据,另外重要的一点是当模型和视图分开后,多个模型的数据可以传递给一个视图进行展示,也可以说一个模型的数据在多个不同的视图中进行 ...
- 一步一步重写 CodeIgniter 框架 (5) —— 实现Controller,并加载Model
CodeIgniter 框架采用MVC模式,而MVC模式中起纽带作用的就是C(控制器),在控制器的中通过加载模型获得数据,将数据传到视图中进行展示.本课将实现在控制器中加载模型. 1. 控制器的实现 ...
- 一步一步重写 CodeIgniter 框架 (3) —— 用面向对象重构代码
前面两篇文章为了重点突出 CodeIgniter 框架的原理,程序的结构很乱,有很多全局变量,在这一课中我们采用面向对象的方法对原先代码进行重构. 到目前为止,程序主要完成的就是 URL 分析,并根据 ...
- 一步一步重写 CodeIgniter 框架 (1) —— url 如何映射到具体的方法
CodeIgniter 框架最显著的特征就是 MVC 模式,它的做法就是提取 url 中的'分段', 映射到某个类的某个方法,从而由该方法来输出最终显示的页面内容.那么我们第一课中就是实现一个这样的原 ...
- 一步一步重写 CodeIgniter 框架 (12) —— 代码再重构,回归 CI
第一课中搭建的基本的 框架模型, 只有一个 index.php 作为执行文件,按这种方式最不稳定的因素就是路径的问题. 我们经常需要通过合适的参数,比如 load_class('output') 或 ...
- 一步一步重写 CodeIgniter 框架 -- 原因和思路
CodeIgniter 是一个非常轻量级的 PHP 框架,说是轻量级,最新版的代码只有不到2M. 其最重要的特点就是 MVC 模式来编写代码,如果大家看过一些用 PHP 来编写网站的书籍或教程,无一例 ...
- 一步一步重写 CodeIgniter 框架 (11) —— 使用 CodeIgniter 函数库
在完成了CI框架的类库扩展后,很自然我们就会想到函数库的扩展.函数库的扩展在 CI 中称为 helper 函数与类有不同的地方,它不能继承,只能覆盖或者添加新的函数,或者直接完全新定义的一组函数. 由 ...
- 一步一步重写 CodeIgniter 框架 (2) —— 实现简单的路由功能
在上一课中,我们实现了简单的根据 URI 执行某个类的某个方法.但是这种映射没有扩展性,对于一个成熟易用的框架肯定是行不通的.那么,我们可以让 框架的用户 通过自定义这种转换来控制,用 CI 的术语就 ...
随机推荐
- jQuery源码,匿名函数自执行
jQuery框架的首尾是这样写的()(), (function(window){//这个window是个入参,随便起个名字都行 //这里面全都是js代码 })(window)//这个括号里的windo ...
- Objective-c 截取子字符串
NSString类中提供了这样三个方法用于获取子字符串: – substringFromIndex: – substringWithRange: – substringToIndex: 它们该怎么使用 ...
- 用JS判断用户使用的是手机端还是pc端访问
最近项目中用到一个应用,当访问同一个网站地址的时候,例如:www.xxx.com的时候,如果当前客户端是pc则跳转到专注于pc的部分,如果当前客户机是手机,则跳转到专注于手机的部分,秉承一贯的习惯,b ...
- iTextSharp.text的一个使用,主要用来创建PDF
using iTextSharp.text; //创建一个字体来使用和编码格式 BaseFont baseFont = BaseFont.CreateFont("C:\\Windows\\F ...
- javascript学习(10)——[知识储备]链式调用
上次我们简单的说了下单例的用法,这个也是在我们java中比较常见的设计模式. 今天简单说下链式调用,可能有很多人并没有听过链式调用,但是其实只要我简单的说下的话,你肯定基本上都在用,大家熟知的jQue ...
- Linux/Mac OS 下 批量提交 新增文件到SVN 服务器
命令行下操作svn没有使用界面形式的TortoiseSVN直观,但是不管怎样,命令行下操作svn还是有它的有点,如果你碰到一次需要svn add许多个文件怎么办?下面的命令可以帮助你解决这个问题 一次 ...
- ThinkPHP文件上传类
TP框架自带文件上传类使用: 类文件在ThinkPHP/Library/Think/默认在目录下 public function upload(){ $upload = new \Think\Uplo ...
- QGraphicsTextItem中的文字对齐
QGraphicsTextItem类可以放到QGraphicsScene或者QGraphicsItem上,用来显示格式化的文本内容,如HTML,当然纯文本也可以显示.如果只是显示纯文本,可以使用QGr ...
- POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割
思路来源:http://blog.csdn.net/lenleaves/article/details/7873441 求最小点权覆盖,同样求一个最小割,但是要求出割去了那些边, 只要用最终的剩余网络 ...
- PLSQL Developer使用技巧整理(转)
一.工具-首选项-用户界面-编辑器-其它-显示行号二.工具-首选项-窗口类型-SQL窗口-显示隔号(行号) 在使用PL/SQL Developer对Procedure进行Debug时,突然发现无法Se ...