• 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

  • 相关阅读:
    swiper获取当前的index ( loop=true时,)
    解决ios浏览器页面滚动到底部或顶部后,页面局部滑动失效的问题
    js实现全屏与退出全屏
    Ueditor 关于视频上传相关问题
    git拉取单个子目录
    XShell上传文件到Linux服务器上
    Debian中安装MySQL服务器
    lamda表达式的由来
    工具类--验证码工具类
    工具类--线程相关工具类
  • 原文地址:https://www.cnblogs.com/ohmygirl/p/CIRead-9.html
Copyright © 2020-2023  润新知