^淡如清风 发表于 2013-9-24 12:04:14

CI的适配器使用经验

本帖最后由 ^淡如清风 于 2013-9-24 15:40 编辑

CI的适配器类有点像抽象类

使用 CodeIgniter 适配器:http://codeigniter.org.cn/user_guide/general/drivers.html
创建适配器:http://codeigniter.org.cn/user_g ... eating_drivers.html

首先看完以上两个教程,5-10分钟

然后转看使用适配器的缓存适配器 :http://codeigniter.org.cn/user_guide/drivers/caching.html

适配器父类:
/application/libraries/Driver_name/Driver_name.php
适配器子类:
/application/libraries/Driver_name/drivers/Driver_name_subclass_1.php
/application/libraries/Driver_name/drivers/Driver_name_subclass_2.php

注意红色子的名称,这个是适配器的名称,全部必须相同
子类名称:命名方法是 适配器的名称(Driver_name)+下划线(_)+子类的名称(subclass_1、_subclass_2)
(另外子类的名称的前缀是可以修改的,继承的类中 给 ib_name 属性赋值,即可改变子类名称前缀的命名,如果没有的话,直接用类名作为子类的前缀名称)

关键点1:什么时候才会载入适配器的子类呢?
由于适配器父类继承自/system/libraries/Driver.php的class CI_Driver_Library
查看源代码可知:
当使用一个属性,且这个属性没有被定义时,这个属性其实就相当于实例化了这个子类,并赋值给这个属性
class CI_Driver_Library {

    protected $valid_drivers    = array();
    protected $lib_name;

    // The first time a child is used it won't exist, so we instantiate it
    // subsequents calls will go straight to the proper child.
    function __get($child)
    {
      if ( ! isset($this->lib_name))
      {
            $this->lib_name = get_class($this);
      }

      // The class will be prefixed with the parent lib
      $child_class = $this->lib_name.'_'.$child;
   
      // Remove the CI_ prefix and lowercase
      $lib_name = ucfirst(strtolower(str_replace('CI_', '', $this->lib_name)));
      $driver_name = strtolower(str_replace('CI_', '', $child_class));
      
      if (in_array($driver_name, array_map('strtolower', $this->valid_drivers)))
      {
            // check and see if the driver is in a separate file
            if ( ! class_exists($child_class))
            {
                // check application path first
                foreach (get_instance()->load->get_package_paths(TRUE) as $path)
                {
                  // loves me some nesting!
                  foreach (array(ucfirst($driver_name), $driver_name) as $class)
                  {
                        $filepath = $path.'libraries/'.$lib_name.'/drivers/'.$class.'.php';

                        if (file_exists($filepath))
                        {
                            include_once $filepath;
                            break;
                        }
                  }
                }

                // it's a valid driver, but the file simply can't be found
                if ( ! class_exists($child_class))
                {
                  log_message('error', "Unable to load the requested driver: ".$child_class);
                  show_error("Unable to load the requested driver: ".$child_class);
                }
            }

            $obj = new $child_class;
            $obj->decorate($this);
            $this->$child = $obj;
            return $this->$child;
      }

      // The requested driver isn't valid!
      log_message('error', "Invalid driver requested: ".$child_class);
      show_error("Invalid driver requested: ".$child_class);
    }

    // --------------------------------------------------------------------

}
// END CI_Driver_Library CLASS

idong 发表于 2015-6-2 16:36:54

说的神马...

idong 发表于 2015-6-2 16:37:07

:@:@:@:@:@:@:@
页: [1]
查看完整版本: CI的适配器使用经验