CodeIgniter 源码解读之控制器

控制器

控制器是你整个应用的中央处理器,当web请求过来时,CI会将取到对应的控制器类和控制器方法,将请求提交给它们,然后进行一系列的业务计算,最终由控制器将处理结果返回给浏览器。这期我们就来看看控制器的实现。

首先,我们来看看控制器核心类(core/Controller.php),这个文件代码很少,哈哈,太高兴了!!!

	/**
	 * Class constructor
	 *
	 * @return	void
	 */
	public function __construct()
	{
		# 将默认路由的 Welcome 对象使用地址引用的方式赋值给 $instance
		self::$instance =& $this;

		// Assign all the class objects that were instantiated by the
		// bootstrap file (CodeIgniter.php) to local class variables
		// so that CI can run as one big super object.
		# 翻译:将通过框架启动文件(CodeIgniter.php)文件实例化的类对象传递给本地类值
		# 以便CI可以当做超级对象使用它们
		foreach (is_loaded() as $var => $class)
		{
			$this->$var =& load_class($class);
		}
		# 加载Loader类并初始化
		$this->load =& load_class('Loader', 'core');
		$this->load->initialize();
		log_message('info', 'Controller Class Initialized');
	}

好吧,我们得去看看Loader类是干嘛的,这里为什么要调用它的 initialize()方法。我有个习惯,遇到一个类,我会先去看他的构造方法,来吧,come on~

	/**
	 * Class constructor
	 *
	 * Sets component load paths, gets the initial output buffering level.
	 *
	 * @return	void
	 */
	public function __construct()
	{
		# 返回输出缓冲机制的嵌套级别,这里的值为 1
		$this->_ci_ob_level = ob_get_level();
		# 很熟悉啦,就是获取已加载的类(Common.php的is_loaded()方法)
		$this->_ci_classes =& is_loaded();
		
		# 写入日志
		log_message('info', 'Loader Class Initialized');
	}

这里的构造方法只做了这么一丢丢事,接着,咱们来看 initialize() 方法。

	/**
	 * Initializer
	 *
	 * @todo	Figure out a way to move this to the constructor
	 *		without breaking *package_path*() methods.
	 * @uses	CI_Loader::_ci_autoloader()
	 * @used-by	CI_Controller::__construct()
	 * @return	void
	 */
	public function initialize()
	{
		# 调用了_ci_autoloader 方法,go~ 走起
		$this->_ci_autoloader();
	}
	// --------------------------------------------------------------------

	/**
	 * CI Autoloader
	 *
	 * Loads component listed in the config/autoload.php file.
	 *
	 * @used-by	CI_Loader::initialize()
	 * @return	void
	 */
	protected function _ci_autoloader()
	{
		# 引入 application\config\autoload.php 文件,文件中是一个 $autoload 数组
		# 这个文件存放着需要自动加载的类库(省去手动加载,提高自动化)
		if (file_exists(APPPATH.'config/autoload.php'))
		{
			include(APPPATH.'config/autoload.php');
		}
		# 如果在开发阶段有自定义的autoload,则覆盖默认的
		if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
		{
			include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
		}
		# 数组不存在则返回
		if ( ! isset($autoload))
		{
			return;
		}

		// Autoload packages
		# 如果autoload.php配置了类库,则将这些类库路径添加到框架中
		if (isset($autoload['packages']))
		{
			foreach ($autoload['packages'] as $package_path)
			{
				# 添加操作
				$this->add_package_path($package_path);
			}
		}

		// Load any custom config file
		# 如果autoload.php配置自定义的配置文件,则加载这些配置类
		if (count($autoload['config']) > 0)
		{
			foreach ($autoload['config'] as $val)
			{
				# 调用本类的 config 方法,添加 配置
				$this->config($val);
			}
		}

		// Autoload helpers and languages
		# 加载辅助函数类及语言类文件
		foreach (array('helper', 'language') as $type)
		{
			if (isset($autoload[$type]) && count($autoload[$type]) > 0)
			{
				$this->$type($autoload[$type]);
			}
		}

		// Autoload drivers
		# 加载各种驱动文件类
		if (isset($autoload['drivers']))
		{
			$this->driver($autoload['drivers']);
		}

		// Load libraries
		# 加载各种类库文件
		if (isset($autoload['libraries']) && count($autoload['libraries']) > 0)
		{
			// Load the database driver.
			# 加载数据库类库驱动
			if (in_array('database', $autoload['libraries']))
			{
				$this->database();
				$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
			}

			// Load all other libraries
			$this->library($autoload['libraries']);
		}

		// Autoload models
		# 加载模型库
		if (isset($autoload['model']))
		{
			$this->model($autoload['model']);
		}
	}

好啦!到此控制器中做的工作就结束类,看了以上代码,我想大家已经都明白了,当实例化我们的控制器类后,框架做了以上的初始化工作。加载了一系列的类库,供我们以后调用。代码其实不难,但控制器是 MVC 的核心,后期的阅读,时不时会回过头来再来看,特别是Loader 类,CI_Controller 的初始化大部分是对 Loader 的初始化,所以,这个 Loader 是在暗示我们,一点要关注他哦~~

好啦~ 今天的源码就说到这里~~,下一篇,我们会一起看 模型

发布了8 篇原创文章 · 获赞 0 · 访问量 167

猜你喜欢

转载自blog.csdn.net/weixin_43950095/article/details/104564402