CI框架源码阅读笔记9 CI的自动加载机制autoload
本篇并不是对某一组件的详细源码分析,而只是简单的跟踪了下CI的autoload的基本流程。因此,可以看做是Loader组件的分析前篇。
CI框架中,允许你配置autoload数组,这样,在你的应用程序初始化时,会自动加载相应的类库,例如,在application/config/autoload.php中,autoload的配置如下:
$autoload['libraries'] = array("smarty", "redis");
则CI框架初始化时,会自动加载libraries下面的smarty.php和redis.php,并且在你的应用程序控制器中,可以通过$this->smarty->xxx 和$this->redis->yyy的方式调用你的类库。
CI允许autoload中配置的自动加载的类别有:
1.Packages ---包
2.Libraries --类库
3.Helper files ---用户自定义的辅助文件
4.Custom config files ---用户自定义配置文件
5.Language files ---语言包
6.Models ---模型类
我们接下来以Libraries的自动加载为例,在追踪CI的autoload之路。
由于Loader是CI中组件加载的管理器,而Loader是在CI_Controller中被加载的,因此我们从Controller加载Loader组件开始追踪。
1. CI_Controller
在CI_Controller中追踪到这样一句话:
$this->load =& load_class('Loader', 'core');
$this->load->initialize();
于是我们猜想,在Loader的initialize的过程中,对autoload做了相应的处理。
2. Loader的initialize方法实现
public function initialize()
{
$this->_ci_classes = array();
$this->_ci_loaded_files = array();
$this->_ci_models = array();
$this->_base_classes =& is_loaded(); $this->_ci_autoloader();//注意这里,看方法的名字,也可以猜到是对autoload的处理
return $this;
}
Initialize的前面四个语句,用于对本身的属性、参数等初始化,不是我们需要关心的内容,真正执行autoload的应该是$this->_ci_autoloader(),沿着该线索,我们进入_ci_autoload的内部:
3. _ci_autoloader的方法:
(1).首先引入autoload的配置数组:
if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
}
else
{
include(APPPATH.'config/autoload.php');
}
(2). 由于我们这次只追踪libraries的autoload机制,因此我们略过对packages和config等的autoload处理机制,而直接寻找对libraries的处理:
if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
{
//ignore database eg.
foreach ($autoload['libraries'] as $item)
{
$this->library($item);
}
}
可以看出,对所有的autoload的libraries,实际上是执行了library方法,再次进入library方法查看。
4. library方法实现。
上述对该方法的调用中,传递的是autoload中配置的类库名(我们的例子是redis和smarty),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);
}
可以看出,如果$library是数组,则会循环调用library方法。实际上最终会调用$this->_ci_load_class。再次进入_ci_load_class查看.
5. _ci_load_class的实现
撇开其中的错误检查和安全检查,我们只看关键的代码:
return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
该方法,将对类库的初始化抛给了_ci_init_class处理:
$CI =& get_instance();//获取Controller的实例
if ($config !== NULL)
{
$CI->$classvar = new $name($config);
}
else
{
$CI->$classvar = new $name;
}
到这里,我们总算了解了CI的autoload的基本流程(漫漫长征),作为对Loader组件的初步追踪,我们省略了中的许多实现细节,这些我们将在对Loader组件的分析过程中慢慢添加上。
总结一下autoload的基本流程:
1. Application/config/autoload.php中配置需要autoload的类库
2. Controller实例化的时候,会加载Loader组件,并调用该组件的initialize方法,对需要的资源初始化.
3. 经过更多的错误检查和安全性检查的步骤,加载需要的类库、配置等。
最后说一句,并不是所有的类库都需要通过CI的autoload加载,因为该类库在框架初始化的时候就被加载,而不管你是不是需要使用该类库,这样实际上会有一定的性能损失。如果你的类库并不是所有应用都需要的,那么,更好的方法是需要时再加载。关于这一点,我们之后在分析Loader组件的设计和实现时会进一步详细说明。
本篇的参考文献:
1. http://itopic.org/codeigniter-config-autoload.html
2. http://codeigniter.org.cn/user_guide/general/autoloader.html
CI框架源码阅读笔记9 CI的自动加载机制autoload的更多相关文章
- CI框架源码阅读笔记5 基准测试 BenchMark.php
上一篇博客(CI框架源码阅读笔记4 引导文件CodeIgniter.php)中,我们已经看到:CI中核心流程的核心功能都是由不同的组件来完成的.这些组件类似于一个一个单独的模块,不同的模块完成不同的功 ...
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...
- CI框架源码阅读笔记3 全局函数Common.php
从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...
- CI框架源码阅读笔记2 一切的入口 index.php
上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...
- CI框架源码阅读笔记1 - 环境准备、基本术语和框架流程
最开始使用CI框架的时候,就打算写一个CI源码阅读的笔记系列,可惜虎头蛇尾,一直没有行动.最近项目少,总算是有了一些时间去写一些东西.于是准备将之前的一些笔记和经验记录下来,一方面权作备忘,另一方面时 ...
- CI框架源码阅读笔记8 控制器Controller.php
最近时间有些紧,源码阅读系列更新有些慢.鉴于Controller中代码比较少,本次Blog先更新该文件的源码分析. 在经过路由分发之后,实际的应用Controller接管用户的所有请求,并负责与用户数 ...
- CI框架源码阅读笔记6 扩展钩子 Hook.php
CI框架允许你在不修改系统核心代码的基础上添加或者更改系统的核心功能(如重写缓存.输出等).例如,在系统开启hook的条件下(config.php中$config['enable_hooks'] = ...
- ****CI框架源码阅读笔记7 配置管理组件 Config.php
http://blog.csdn.net/ohmygirl/article/details/41041597 一个灵活可控的应用程序中,必然会存在大量的可控参数(我们称为配置),例如在CI的主配置文件 ...
- Spring5.0源码学习系列之浅谈懒加载机制原理
前言介绍 附录:Spring源码学习专栏 在上一章的学习中,我们对Bean的创建有了一个粗略的了解,接着本文挑一个比较重要的知识点Bean的懒加载进行学习 1.什么是懒加载? 懒加载(Lazy-ini ...
随机推荐
- Linux快速入门03-系统管理
这部分将涉及常用的各类linux命令和一些系统高级管理特性,尤其是shell script的创建,这部分在系统自动化运维时会很有作用. Linux系列文章 快速入门系列--Linux--01基础概念 ...
- 为什么SQL语句Where 1=1 and在SQL Server中不影响性能
最近一个朋友和我探讨关于Where 1=1 and这种形式的语句会不会影响性能.最后结论是不影响. 虽然结论正确,但对问题的认识却远远没有解决问题的根本.实际上在T-SQL语句的书写过 ...
- Tcl Tk Introduction
Tcl Tk Introduction eryar@163.com 摘要Abstract:Tcl/Tck脚本可以很容易实现用户自定义的命令,方便的创建图形化的用户界面GUI,所以Tcl和Tk的应用领域 ...
- Android开发之广播
广播是Android开发中的一个重要的功能,在Android里面有各式各样的广播,比如:电池的状态变化.信号的强弱状态.电话的接听和短信的接收等等,现在给大家简单介绍一下系统发送.监听这些广播的机制. ...
- 【原创】C#搭建足球赛事资料库与预测平台(6) 赔率数据表设计2
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源C#彩票数据资料库系列文章总目录:[目录]C#搭建足球赛事资料库与预测平台与彩票数据分析目录 本篇文章开始将逐步介 ...
- 数据可视化(7)--D3基础
一直想写写D3,觉得D3真心比较强大,基本上你能想出来的图表都能绘制出来,只不过使用起来比前几个要稍麻烦一点. 正好最近读完了<数据可视化实战>,将关于D3的知识梳理了一遍,写这篇博客记录 ...
- Hadoop阅读笔记(四)——一幅图看透MapReduce机制
时至今日,已然看到第十章,似乎越是焦躁什么时候能翻完这本圣经的时候也让自己变得更加浮躁,想想后面还有一半的行程没走,我觉得这样“有口无心”的学习方式是不奏效的,或者是收效甚微的.如果有幸能有大牛路过, ...
- JavaScript变量和数据类型
变量 变量就是一个元素,类似于数学中的概念,用来指定表示一个对象.在JavaScript中,用来指定变量的关键字为var.当声明新变量时,可以使用关键词 "new" 来声明其类型 ...
- Go语言接口
接口是面向对象的必备属性之一,即便是像C语言这种面向过程的语言也可以通过指向函数的指针来实现接口.我们熟知的面向对象语言中更是少不了接口.最近闲了下来,又可以开始学习Go语言了,发现Go语言的接口吸收 ...
- C#进行Visio二次开发之文件导出及另存Web页面
在我前面很多关于Visio的开发过程中,介绍了各种Visio的C#开发应用场景,包括对Visio的文档.模具文档.形状.属性数据.各种事件等相关的基础处理,以及Visio本身的整体项目应用,虽然时间过 ...