本篇博文讲述超级控制器类文件Controller.php,大家一看这个文件名肯定是非常的兴奋,这个Controller,就是我们通常所说的MVC中的C。这个文件就是我们在开发项目过程中开发控制器是所有的控制器类都要继承自这个文件。在经过路由分发之后,实际的应用Controller接管用户的所有请求,并负责与用户数据的交互。CI中所有的应用控制器都应该是CI_Controller的子类(除非你扩展了CI的核心,那么你的Controller父类可以是MY_Controller)。
在应用程序控制器中,我们经常会用到这样的代码:
//加载配置文件 $this->load->config("config_app"); //加载model $this->load->model("user"); //加载视图 $this->load->view("index"); //获取post $this->input->post("data",true); //获取 get $this->input->get("data",true); //清除xss $this->security->xss_clean($data); //mark时间点 $this->benchmark->mark("app_start");
这些是如何实现的?我们接下来就简单跟踪一下。尽管这个类的结构很简单,但是这个类非常重要,我们下面就一点一点的分析一下这个类的成员。
1、构造函数(_contruct())
/** * 构造函数 */ public function __construct() { self::$instance =& $this; //这里将所有加载的组件都给超级控制器 foreach (is_loaded() as $var => $class) { $this->$var =& load_class($class); } $this->load =& load_class('Loader', 'core'); //初始化Loader组件,详细Loader.php $this->load->initialize(); log_message('info', 'Controller Class Initialized'); }
这里CI做了一个处理,通过循环将所有的已经加载的组件加入CI_Controller(前面我们已经看到,is_loaded函数追踪所有加载的组件)。这就解释了为什么我们可以通过$this->input等方式来调用CI的组件。但是这还不够,所以类文件顺便把Loader也搞进来了。现在,可以使用Loader组件来加载配置($this->load->config),加载模型($this->load->model) 和加载视图了($this->load->view)。CI_Controller可以说是一个持有多个组件的超级类,这样的方式,非常类似于设计模式中的"代理模式"。
2、实例化对象(&get_instance())
/** * 创建一个用来实例化对象的方法 */ public static function &get_instance() { return self::$instance; }
这里简单解释一下,CI_Controller是一个单例模式的类,通过get_instance()方法获得该类的实例。CodeIgniter.php中get_instance函数调用的即是该方法。以下是关于Controller的一些Hint:
Ⅰ CI框架中Controller中可以自定义目录,例如在application/controller目录中创建目录admin,并新建IndexController,则该Controller的URL访问路径是:www.citest.com/admin/index/method
Ⅱ Controller中不应该承担过多的逻辑,业务逻辑应该封装到Model中.
Ⅲ 你的Controller应该按照业务区分,例如UserController处理用户相关的请求,而AppController处理应用的请求等,这不是原则,而只是一种方式。
Ⅳ Controller类名应该以大写字母开头,文件名应该是全小写的形式。
Ⅴ Controller中以下划线开头的方法被CI认为是私有方法,不能够被外部直接访问。
以上就是Controller的全部内容了,最后,按照惯例贴一下整个超级控制器类Controller.php文件的源码(注释版):
<?php
/**
* =======================================
* Created by Pocket Knife Technology.
* User: ZhiHua_W
* Date: 2016/10/27 0013
* Time: 下午 5:11
* Project: CodeIgniter框架—源码分析
* Power: Analysis for Controller.php
* =======================================
*/
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CI超级控制器,controller所有文件都得继承超级CI_Controller
*/
class CI_Controller
{
//定义保存单例的静态成员变量
private static $instance;
/**
* 构造函数
*/
public function __construct()
{
//通过self::$instance实现单例化,在第一次实例时,这个静态变量实质就是引用了这个实例。
//以后都可以通过&get_instance();来获得这个单一实例。
self::$instance =& $this;
//把目前程序已经加载的所有的组件都给这个超级控制器来掌管。
//is_load()是CodeIgniter.php中记录加载类名的数组
//这里将所有加载的组件都给超级控制器
foreach (is_loaded() as $var => $class) {
$this->$var =& load_class($class);
}
//给超级控制器加载Loader组件,这个组件是它的好助手,
//很多时候你会经常用到$this->load->xxx()的形式加载某个东西,
//这个load就是控制器被构造的时候就伴随存在的。
$this->load =& load_class('Loader', 'core');
//初始化Loader组件,详细Loader.php
$this->load->initialize();
log_message('info', 'Controller Class Initialized');
}
/**
* 创建一个用来实例化对象的方法
*/
public static function &get_instance()
{
return self::$instance;
}
}