当前位置:首页 > CMS教程 > 其它CMS > 列表

CI框架装载器Loader.php源码分析

发布:smiling 来源: PHP粉丝网  添加日期:2021-04-23 10:27:33 浏览: 评论:0 

前面我们分析了CI框架的session类和安全类文件,今天我们来分析下CI框架的装载器Loader.php文件的源码

顾名思义,装载器就是加载元素的,使用CI时,经常加载的有:

  1. $this->load->library() 
  2. $this->load->view() 
  3. $this->load->model() 
  4. $this->load->database() 
  5. $this->load->helper() 
  6. $this->load->config() 
  7. $this->load->add_package_path() 

代码如下:

  1. /** 
  2.  * Loader Class 
  3.  * 
  4.  * 用户加载views和files,常见的函数有model(),view(),library(),helper() 
  5.  * 
  6.  * Controller的好助手,$this->load =& load_class('Loader', 'core');,加载了loader,Controller就无比强大了 
  7.  */ 
  8. class CI_Loader { 
  9.  protected $_ci_ob_level
  10.  protected $_ci_view_paths  = array(); 
  11.  protected $_ci_library_paths = array(); 
  12.  protected $_ci_model_paths  = array(); 
  13.  protected $_ci_helper_paths  = array(); 
  14.  protected $_base_classes  = array(); // Set by the controller class 
  15.  protected $_ci_cached_vars  = array(); 
  16.  protected $_ci_classes   = array(); 
  17.  protected $_ci_loaded_files  = array(); 
  18.  
  19.  protected $_ci_models   = array(); 
  20.  protected $_ci_helpers   = array(); 
  21.  protected $_ci_varmap   = array('unit_test' => 'unit'
  22.            'user_agent' => 'agent'); 
  23.  public function __construct() 
  24.  {       
  25.                 //获取缓冲嵌套级别 
  26.   $this->_ci_ob_level  = ob_get_level(); 
  27.   //library路径 
  28.                 $this->_ci_library_paths = array(APPPATH, BASEPATH); 
  29.                 //helper路径 
  30.   $this->_ci_helper_paths = array(APPPATH, BASEPATH); 
  31.                 //model路径 
  32.   $this->_ci_model_paths = array(APPPATH); 
  33.                 //view路径 
  34.   $this->_ci_view_paths = array(APPPATH.'views/' => TRUE); 
  35.   log_message('debug'"Loader Class Initialized"); 
  36.  } 
  37.  // -------------------------------------------------------------------- 
  38.  /** 
  39.   * 初始化Loader 
  40.   * 
  41.   */ 
  42.  public function initialize() 
  43.  { 
  44.   $this->_ci_classes = array(); 
  45.   $this->_ci_loaded_files = array(); 
  46.   $this->_ci_models = array(); 
  47.                 //将is_loaded(common中记录加载核心类函数)加载的核心类交给_base_classes 
  48.   $this->_base_classes =& is_loaded(); 
  49.                 //加载autoload.php配置中文件 
  50.   $this->_ci_autoloader(); 
  51.   return $this
  52.  } 
  53.  // -------------------------------------------------------------------- 
  54.  /** 
  55.   * 检测类是否加载 
  56.   */ 
  57.  public function is_loaded($class
  58.  { 
  59.   if (isset($this->_ci_classes[$class])) 
  60.   { 
  61.    return $this->_ci_classes[$class]; 
  62.   } 
  63.   return FALSE; 
  64.  } 
  65.  // -------------------------------------------------------------------- 
  66.  /** 
  67.   * 加载Class 
  68.   */ 
  69.  public function library($library = ''$params = NULL, $object_name = NULL) 
  70.  { 
  71.   if (is_array($library)) 
  72.   { 
  73.    foreach ($library as $class
  74.    { 
  75.     $this->library($class$params); 
  76.    } 
  77.    return
  78.   } 
  79.                 //如果$library为空或者已经加载。。。 
  80.   if ($library == '' OR isset($this->_base_classes[$library])) 
  81.   { 
  82.    return FALSE; 
  83.   } 
  84.   if ( ! is_null($params) && ! is_array($params)) 
  85.   { 
  86.    $params = NULL; 
  87.   } 
  88.   $this->_ci_load_class($library$params$object_name); 
  89.  } 
  90.  // -------------------------------------------------------------------- 
  91.  /** 
  92.   * 加载和实例化model 
  93.   */ 
  94.  public function model($model$name = ''$db_conn = FALSE) 
  95.  { 
  96.                 //CI支持数组加载多个model 
  97.   if (is_array($model)) 
  98.   { 
  99.    foreach ($model as $babe
  100.    { 
  101.     $this->model($babe); 
  102.    } 
  103.    return
  104.   } 
  105.   if ($model == ''
  106.   { 
  107.    return
  108.   } 
  109.   $path = ''
  110.   // 是否存在子目录 
  111.   if (($last_slash = strrpos($model'/')) !== FALSE) 
  112.   { 
  113.    // The path is in front of the last slash 
  114.    $path = substr($model, 0, $last_slash + 1); 
  115.    // And the model name behind it 
  116.    $model = substr($model$last_slash + 1); 
  117.   } 
  118.   if ($name == ''
  119.   { 
  120.    $name = $model
  121.   } 
  122.   if (in_array($name$this->_ci_models, TRUE)) 
  123.   { 
  124.    return
  125.   } 
  126.   $CI =& get_instance(); 
  127.   if (isset($CI->$name)) 
  128.   { 
  129.    show_error('The model name you are loading is the name of a resource that is already being used: '.$name); 
  130.   } 
  131.   $model = strtolower($model); //model文件名全小写 
  132.   foreach ($this->_ci_model_paths as $mod_path
  133.   { 
  134.    if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) 
  135.    { 
  136.     continue
  137.    } 
  138.    if ($db_conn !== FALSE AND ! class_exists('CI_DB')) 
  139.    { 
  140.     if ($db_conn === TRUE) 
  141.     { 
  142.      $db_conn = ''
  143.     } 
  144.     $CI->load->database($db_conn, FALSE, TRUE); 
  145.    } 
  146.    if ( ! class_exists('CI_Model')) 
  147.    { 
  148.     load_class('Model''core'); 
  149.    } 
  150.    require_once($mod_path.'models/'.$path.$model.'.php'); 
  151.    $model = ucfirst($model); 
  152.    $CI->$name = new $model(); 
  153.                         //保存在Loader::_ci_models中,以后可以用它来判断某个model是否已经加载过。 
  154.    $this->_ci_models[] = $name
  155.    return
  156.   } 
  157.   // couldn't find the model 
  158.   show_error('Unable to locate the model you have specified: '.$model); 
  159.  } 
  160.  // -------------------------------------------------------------------- 
  161.  /** 
  162.   * 数据库Loader 
  163.   */ 
  164.  public function database($params = ''$return = FALSE, $active_record = NULL) 
  165.  { 
  166.   // Grab the super object 
  167.   $CI =& get_instance(); 
  168.   // 是否需要加载db 
  169.   if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db)) 
  170.   { 
  171.    return FALSE; 
  172.   } 
  173.   require_once(BASEPATH.'database/DB.php'); 
  174.   if ($return === TRUE) 
  175.   { 
  176.    return DB($params$active_record); 
  177.   } 
  178.   // Initialize the db variable.  Needed to prevent 
  179.   // reference errors with some configurations 
  180.   $CI->db = ''
  181.   // Load the DB class 
  182.   $CI->db =& DB($params$active_record); 
  183.  } 
  184.  // -------------------------------------------------------------------- 
  185.  /** 
  186.   * 加载数据库工具类 
  187.   */ 
  188.  public function dbutil() 
  189.  { 
  190.   if ( ! class_exists('CI_DB')) 
  191.   { 
  192.    $this->database(); 
  193.   } 
  194.   $CI =& get_instance(); 
  195.   // for backwards compatibility, load dbforge so we can extend dbutils off it 
  196.   // this use is deprecated and strongly discouraged 
  197.   $CI->load->dbforge(); 
  198.   require_once(BASEPATH.'database/DB_utility.php'); 
  199.   require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility.php'); 
  200.   $class = 'CI_DB_'.$CI->db->dbdriver.'_utility'
  201.   $CI->dbutil = new $class(); 
  202.  } 
  203.  // -------------------------------------------------------------------- 
  204.  /** 
  205.   * Load the Database Forge Class 
  206.   * 
  207.   * @return string 
  208.   */ 
  209.  public function dbforge() 
  210.  { 
  211.   if ( ! class_exists('CI_DB')) 
  212.   { 
  213.    $this->database(); 
  214.   } 
  215.   $CI =& get_instance(); 
  216.   require_once(BASEPATH.'database/DB_forge.php'); 
  217.   require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php'); 
  218.   $class = 'CI_DB_'.$CI->db->dbdriver.'_forge'
  219.   $CI->dbforge = new $class(); 
  220.  } 
  221.  // -------------------------------------------------------------------- 
  222.  /** 
  223.   * 加载视图文件 
  224.   */ 
  225.  public function view($view$vars = array(), $return = FALSE) 
  226.  { 
  227.   return $this->_ci_load(array('_ci_view' => $view'_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return)); 
  228.  } 
  229.  // -------------------------------------------------------------------- 
  230.  /** 
  231.   * 加载普通文件 
  232.   */ 
  233.  public function file($path$return = FALSE) 
  234.  { 
  235.   return $this->_ci_load(array('_ci_path' => $path'_ci_return' => $return)); 
  236.  } 
  237.  // -------------------------------------------------------------------- 
  238.  /** 
  239.   * 设置变量 
  240.   * 
  241.   * Once variables are set they become available within 
  242.   * the controller class and its "view" files. 
  243.   * 
  244.   */ 
  245.  public function vars($vars = array(), $val = ''
  246.  { 
  247.   if ($val != '' AND is_string($vars)) 
  248.   { 
  249.    $vars = array($vars => $val); 
  250.   } 
  251.   $vars = $this->_ci_object_to_array($vars); 
  252.   if (is_array($vars) AND count($vars) > 0) 
  253.   { 
  254.    foreach ($vars as $key => $val
  255.    { 
  256.     $this->_ci_cached_vars[$key] = $val
  257.    } 
  258.   } 
  259.  } 
  260.  // -------------------------------------------------------------------- 
  261.  /** 
  262.   * 检查并获取变量 
  263.   */ 
  264.  public function get_var($key
  265.  { 
  266.   return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL; 
  267.  } 
  268.  // -------------------------------------------------------------------- 
  269.  /** 
  270.   * 加载helper 
  271.   */ 
  272.  public function helper($helpers = array()) 
  273.  { 
  274.   foreach ($this->_ci_prep_filename($helpers'_helper'as $helper
  275.   { 
  276.    if (isset($this->_ci_helpers[$helper])) 
  277.    { 
  278.     continue
  279.    } 
  280.    $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.'.php'
  281.    // 如果是扩展helper的话 
  282.    if (file_exists($ext_helper)) 
  283.    { 
  284.     $base_helper = BASEPATH.'helpers/'.$helper.'.php'
  285.     if ( ! file_exists($base_helper)) 
  286.     { 
  287.      show_error('Unable to load the requested file: helpers/'.$helper.'.php'); 
  288.     } 
  289.     include_once($ext_helper); 
  290.     include_once($base_helper); 
  291.     $this->_ci_helpers[$helper] = TRUE; 
  292.     log_message('debug''Helper loaded: '.$helper); 
  293.     continue
  294.    } 
  295.    // 如果不是扩展helper,helper路径中加载helper 
  296.    foreach ($this->_ci_helper_paths as $path
  297.    { 
  298.     if (file_exists($path.'helpers/'.$helper.'.php')) 
  299.     { 
  300.      include_once($path.'helpers/'.$helper.'.php'); 
  301.      $this->_ci_helpers[$helper] = TRUE; 
  302.      log_message('debug''Helper loaded: '.$helper); 
  303.      break
  304.     } 
  305.    } 
  306.    // 如果该helper还没加载成功的话,说明加载helper失败 
  307.    if ( ! isset($this->_ci_helpers[$helper])) 
  308.    { 
  309.     show_error('Unable to load the requested file: helpers/'.$helper.'.php'); 
  310.    } 
  311.   } 
  312.  } 
  313.  // -------------------------------------------------------------------- 
  314.  /** 
  315.   * 可以看到helpers调用也是上面的helper,只是helpers的别名而已 
  316.   */ 
  317.  public function helpers($helpers = array()) 
  318.  { 
  319.   $this->helper($helpers); 
  320.  } 
  321.  // -------------------------------------------------------------------- 
  322.  /** 
  323.   * 加载language文件 
  324.   */ 
  325.  public function language($file = array(), $lang = ''
  326.  { 
  327.   $CI =& get_instance(); 
  328.   if ( ! is_array($file)) 
  329.   { 
  330.    $file = array($file); 
  331.   } 
  332.   foreach ($file as $langfile
  333.   { 
  334.    $CI->lang->load($langfile$lang); 
  335.   } 
  336.  } 
  337.  // -------------------------------------------------------------------- 
  338.  /** 
  339.   * 加载配置文件 
  340.   */ 
  341.  public function config($file = ''$use_sections = FALSE, $fail_gracefully = FALSE) 
  342.  { 
  343.   $CI =& get_instance(); 
  344.   $CI->config->load($file$use_sections$fail_gracefully); 
  345.  } 
  346.  // -------------------------------------------------------------------- 
  347.  /** 
  348.   * Driver 
  349.   * 
  350.   * 加载 driver library 
  351.   */ 
  352.  public function driver($library = ''$params = NULL, $object_name = NULL) 
  353.  { 
  354.   if ( ! class_exists('CI_Driver_Library')) 
  355.   { 
  356.    // we aren't instantiating an object here, that'll be done by the Library itself 
  357.    require BASEPATH.'libraries/Driver.php'
  358.   } 
  359.   if ($library == ''
  360.   { 
  361.    return FALSE; 
  362.   } 
  363.   // We can save the loader some time since Drivers will *always* be in a subfolder, 
  364.   // and typically identically named to the library 
  365.   if ( ! strpos($library'/')) 
  366.   { 
  367.    $library = ucfirst($library).'/'.$library
  368.   } 
  369.   return $this->library($library$params$object_name); 
  370.  } 
  371.  // -------------------------------------------------------------------- 
  372.  /** 
  373.   * 添加 Package 路径 
  374.   * 
  375.   * 把package路径添加到库,模型,助手,配置路径 
  376.   */ 
  377.  public function add_package_path($path$view_cascade=TRUE) 
  378.  { 
  379.   $path = rtrim($path'/').'/'
  380.   array_unshift($this->_ci_library_paths, $path); 
  381.   array_unshift($this->_ci_model_paths, $path); 
  382.   array_unshift($this->_ci_helper_paths, $path); 
  383.   $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths; 
  384.   $config =& $this->_ci_get_component('config'); 
  385.   array_unshift($config->_config_paths, $path); 
  386.  } 
  387.  // -------------------------------------------------------------------- 
  388.  /** 
  389.   * 获取Package Paths,默认不包含BASEPATH 
  390.   */ 
  391.  public function get_package_paths($include_base = FALSE) 
  392.  { 
  393.   return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths; 
  394.  } 
  395.  // -------------------------------------------------------------------- 
  396.  /** 
  397.   * 剔除Package Path 
  398.   * 
  399.   * Remove a path from the library, model, and helper path arrays if it exists 
  400.   * If no path is provided, the most recently added path is removed. 
  401.   * 
  402.   */ 
  403.  public function remove_package_path($path = ''$remove_config_path = TRUE) 
  404.  { 
  405.   $config =& $this->_ci_get_component('config'); 
  406.   if ($path == ''
  407.   { 
  408.    $void = array_shift($this->_ci_library_paths); 
  409.    $void = array_shift($this->_ci_model_paths); 
  410.    $void = array_shift($this->_ci_helper_paths); 
  411.    $void = array_shift($this->_ci_view_paths); 
  412.    $void = array_shift($config->_config_paths); 
  413.   } 
  414.   else 
  415.   { 
  416.    $path = rtrim($path'/').'/'
  417.    foreach (array('_ci_library_paths''_ci_model_paths''_ci_helper_paths'as $var
  418.    { 
  419.     if (($key = array_search($path$this->{$var})) !== FALSE) 
  420.     { 
  421.      unset($this->{$var}[$key]); 
  422.     } 
  423.    } 
  424.    if (isset($this->_ci_view_paths[$path.'views/'])) 
  425.    { 
  426.     unset($this->_ci_view_paths[$path.'views/']); 
  427.    } 
  428.    if (($key = array_search($path$config->_config_paths)) !== FALSE) 
  429.    { 
  430.     unset($config->_config_paths[$key]); 
  431.    } 
  432.   } 
  433.   // 保证应用默认的路径依然存在 
  434.   $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH))); 
  435.   $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH))); 
  436.   $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH))); 
  437.   $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE)); 
  438.   $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH))); 
  439.  } 
  440.  // -------------------------------------------------------------------- 
  441.  /** 
  442.   * Loader 
  443.   * 
  444.   * This function is used to load views and files. 
  445.   * Variables are prefixed with _ci_ to avoid symbol collision with 
  446.   * variables made available to view files 
  447.   * 
  448.   * @param array 
  449.   * @return void 
  450.   */ 
  451.  protected function _ci_load($_ci_data
  452.  { 
  453.   // Set the default data variables 
  454.   foreach (array('_ci_view''_ci_vars''_ci_path''_ci_return'as $_ci_val
  455.   { 
  456.    $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val]; 
  457.   } 
  458.   $file_exists = FALSE; 
  459.                 //如果$_ci_path不为空,则说明当前要加载普通文件。Loader::file才会有path 
  460.   if ($_ci_path != ''
  461.   { 
  462.    $_ci_x = explode('/'$_ci_path); 
  463.    $_ci_file = end($_ci_x); 
  464.   } 
  465.   else 
  466.   { 
  467.    $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); 
  468.    $_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view
  469.    foreach ($this->_ci_view_paths as $view_file => $cascade
  470.    { 
  471.     if (file_exists($view_file.$_ci_file)) 
  472.     { 
  473.      $_ci_path = $view_file.$_ci_file
  474.      $file_exists = TRUE; 
  475.      break
  476.     } 
  477.     if ( ! $cascade
  478.     { 
  479.      break
  480.     } 
  481.    } 
  482.   } 
  483.                 //view文件不存在则会报错 
  484.   if ( ! $file_exists && ! file_exists($_ci_path)) 
  485.   { 
  486.    show_error('Unable to load the requested file: '.$_ci_file); 
  487.   } 
  488.   // 把CI的所有属性都传递给loader,view中$this指的是loader 
  489.   $_ci_CI =& get_instance(); 
  490.   foreach (get_object_vars($_ci_CIas $_ci_key => $_ci_var
  491.   { 
  492.    if ( ! isset($this->$_ci_key)) 
  493.    { 
  494.     $this->$_ci_key =& $_ci_CI->$_ci_key
  495.    } 
  496.   } 
  497.   /* 
  498.    * Extract and cache variables 
  499.    * 
  500.    * You can either set variables using the dedicated $this->load_vars() 
  501.    * function or via the second parameter of this function. We'll merge 
  502.    * the two types and cache them so that views that are embedded within 
  503.    * other views can have access to these variables. 
  504.    */ 
  505.   if (is_array($_ci_vars)) 
  506.   { 
  507.    $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); 
  508.   } 
  509.   extract($this->_ci_cached_vars); 
  510.   /* 
  511.    * 将视图内容放到缓存区 
  512.    * 
  513.    */ 
  514.   ob_start(); 
  515.   // 支持短标签 
  516.   if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE) 
  517.   { 
  518.    echo eval('?>'.preg_replace("/;*\s*\?>/""; ?>"str_replace('<?=''<?php echo 'file_get_contents($_ci_path)))); 
  519.   } 
  520.   else 
  521.   { 
  522.    include($_ci_path); // include() vs include_once() allows for multiple views with the same name 
  523.   } 
  524.   log_message('debug''File loaded: '.$_ci_path); 
  525.   // 是否直接返回view数据 
  526.   if ($_ci_return === TRUE) 
  527.   { 
  528.    $buffer = ob_get_contents(); 
  529.    @ob_end_clean(); 
  530.    return $buffer
  531.   } 
  532.   //当前这个视图文件是被另一个视图文件通过$this->view()方法引入,即视图文件嵌入视图文件 
  533.   if (ob_get_level() > $this->_ci_ob_level + 1) 
  534.   { 
  535.    ob_end_flush(); 
  536.   } 
  537.   else 
  538.   {       ////把缓冲区的内容交给Output组件并清空关闭缓冲区。 
  539.    $_ci_CI->output->append_output(ob_get_contents()); 
  540.    @ob_end_clean(); 
  541.   } 
  542.  } 
  543.  // -------------------------------------------------------------------- 
  544.  /** 
  545.   * 加载类 
  546.   */ 
  547.  protected function _ci_load_class($class$params = NULL, $object_name = NULL) 
  548.  { 
  549.   // 去掉.php和两端的/获取的$class就是类名或目录名+类名 
  550.   $class = str_replace('.php''', trim($class'/')); 
  551.   // CI允许dir/filename方式 
  552.   $subdir = ''
  553.   if (($last_slash = strrpos($class'/')) !== FALSE) 
  554.   { 
  555.    // 目录 
  556.    $subdir = substr($class, 0, $last_slash + 1); 
  557.    // 文件名 
  558.    $class = substr($class$last_slash + 1); 
  559.   } 
  560.   // 允许加载的类名首字母大写或全小写 
  561.   foreach (array(ucfirst($class), strtolower($class)) as $class
  562.   { 
  563.    $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php'
  564.    // 是否是扩展类 
  565.    if (file_exists($subclass)) 
  566.    { 
  567.     $baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php'
  568.     if ( ! file_exists($baseclass)) 
  569.     { 
  570.      log_message('error'"Unable to load the requested class: ".$class); 
  571.      show_error("Unable to load the requested class: ".$class); 
  572.     } 
  573.     // Safety:  Was the class already loaded by a previous call? 
  574.     if (in_array($subclass$this->_ci_loaded_files)) 
  575.     { 
  576.      // Before we deem this to be a duplicate request, let's see 
  577.      // if a custom object name is being supplied.  If so, we'll 
  578.      // return a new instance of the object 
  579.      if ( ! is_null($object_name)) 
  580.      { 
  581.       $CI =& get_instance(); 
  582.       if ( ! isset($CI->$object_name)) 
  583.       { 
  584.        return $this->_ci_init_class($class, config_item('subclass_prefix'), $params$object_name); 
  585.       } 
  586.      } 
  587.      $is_duplicate = TRUE; 
  588.      log_message('debug'$class." class already loaded. Second attempt ignored."); 
  589.      return
  590.     } 
  591.     include_once($baseclass); 
  592.     include_once($subclass); 
  593.     $this->_ci_loaded_files[] = $subclass
  594.                                 //实例化类 
  595.     return $this->_ci_init_class($class, config_item('subclass_prefix'), $params$object_name); 
  596.    } 
  597.    // 如果不是扩展,和上面类似 
  598.    $is_duplicate = FALSE; 
  599.    foreach ($this->_ci_library_paths as $path
  600.    { 
  601.     $filepath = $path.'libraries/'.$subdir.$class.'.php'
  602.     // Does the file exist?  No?  Bummer... 
  603.     if ( ! file_exists($filepath)) 
  604.     { 
  605.      continue
  606.     } 
  607.     // Safety:  Was the class already loaded by a previous call? 
  608.     if (in_array($filepath$this->_ci_loaded_files)) 
  609.     { 
  610.      // Before we deem this to be a duplicate request, let's see 
  611.      // if a custom object name is being supplied.  If so, we'll 
  612.      // return a new instance of the object 
  613.      if ( ! is_null($object_name)) 
  614.      { 
  615.       $CI =& get_instance(); 
  616.       if ( ! isset($CI->$object_name)) 
  617.       { 
  618.        return $this->_ci_init_class($class''$params$object_name); 
  619.       } 
  620.      } 
  621.      $is_duplicate = TRUE; 
  622.      log_message('debug'$class." class already loaded. Second attempt ignored."); 
  623.      return
  624.     } 
  625.     include_once($filepath); 
  626.     $this->_ci_loaded_files[] = $filepath
  627.     return $this->_ci_init_class($class''$params$object_name); 
  628.    } 
  629.   } // END FOREACH 
  630.   // 如果还没有找到该class,最后的尝试是该class会不会在同名的子目录下 
  631.   if ($subdir == ''
  632.   { 
  633.    $path = strtolower($class).'/'.$class
  634.    return $this->_ci_load_class($path$params); 
  635.   } 
  636.   // 加载失败,报错 
  637.   if ($is_duplicate == FALSE) 
  638.   { 
  639.    log_message('error'"Unable to load the requested class: ".$class); 
  640.    show_error("Unable to load the requested class: ".$class); 
  641.   } 
  642.  } 
  643.  // -------------------------------------------------------------------- 
  644.  /** 
  645.   * 实例化已经加载的类 
  646.   */ 
  647.  protected function _ci_init_class($class$prefix = ''$config = FALSE, $object_name = NULL) 
  648.  { 
  649.   // 是否有类的配置信息 
  650.   if ($config === NULL) 
  651.   { 
  652.    // Fetch the config paths containing any package paths 
  653.    $config_component = $this->_ci_get_component('config'); 
  654.    if (is_array($config_component->_config_paths)) 
  655.    { 
  656.     // Break on the first found file, thus package files 
  657.     // are not overridden by default paths 
  658.     foreach ($config_component->_config_paths as $path
  659.     { 
  660.      // We test for both uppercase and lowercase, for servers that 
  661.      // are case-sensitive with regard to file names. Check for environment 
  662.      // first, global next 
  663.      if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')) 
  664.      { 
  665.       include($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'); 
  666.       break
  667.      } 
  668.      elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')) 
  669.      { 
  670.       include($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'); 
  671.       break
  672.      } 
  673.      elseif (file_exists($path .'config/'.strtolower($class).'.php')) 
  674.      { 
  675.       include($path .'config/'.strtolower($class).'.php'); 
  676.       break
  677.      } 
  678.      elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).'.php')) 
  679.      { 
  680.       include($path .'config/'.ucfirst(strtolower($class)).'.php'); 
  681.       break
  682.      } 
  683.     } 
  684.    } 
  685.   } 
  686.   if ($prefix == ''
  687.   {       //system下library 
  688.    if (class_exists('CI_'.$class)) 
  689.    { 
  690.     $name = 'CI_'.$class
  691.    } 
  692.    elseif (class_exists(config_item('subclass_prefix').$class)) 
  693.    {       //扩展library 
  694.     $name = config_item('subclass_prefix').$class
  695.    } 
  696.    else 
  697.    { 
  698.     $name = $class
  699.    } 
  700.   } 
  701.   else 
  702.   { 
  703.    $name = $prefix.$class
  704.   } 
  705.   // Is the class name valid? 
  706.   if ( ! class_exists($name)) 
  707.   { 
  708.    log_message('error'"Non-existent class: ".$name); 
  709.    show_error("Non-existent class: ".$class); 
  710.   } 
  711.   // Set the variable name we will assign the class to 
  712.   // Was a custom class name supplied?  If so we'll use it 
  713.   $class = strtolower($class); 
  714.   if (is_null($object_name)) 
  715.   { 
  716.    $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class]; 
  717.   } 
  718.   else 
  719.   { 
  720.    $classvar = $object_name
  721.   } 
  722.   // Save the class name and object name 
  723.   $this->_ci_classes[$class] = $classvar
  724.   // 将初始化的类的实例给CI超级句柄 
  725.   $CI =& get_instance(); 
  726.   if ($config !== NULL) 
  727.   { 
  728.    $CI->$classvar = new $name($config); 
  729.   } 
  730.   else 
  731.   { 
  732.    $CI->$classvar = new $name
  733.   } 
  734.  } 
  735.  // -------------------------------------------------------------------- 
  736.  /** 
  737.   * 自动加载器 
  738.          * 
  739.          * autoload.php配置的自动加载文件有: 
  740.          *  | 1. Packages 
  741.             | 2. Libraries 
  742.             | 3. Helper files 
  743.             | 4. Custom config files 
  744.             | 5. Language files 
  745.             | 6. Models 
  746.   */ 
  747.  private function _ci_autoloader() 
  748.  { 
  749.   if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')) 
  750.   { 
  751.    include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'); 
  752.   } 
  753.   else 
  754.   { 
  755.    include(APPPATH.'config/autoload.php'); 
  756.   } 
  757.   if ( ! isset($autoload)) 
  758.   { 
  759.    return FALSE; 
  760.   } 
  761.   // 自动加载packages,也就是将package_path加入到library,model,helper,config 
  762.   if (isset($autoload['packages'])) 
  763.   { 
  764.    foreach ($autoload['packages'as $package_path
  765.    { 
  766.     $this->add_package_path($package_path); 
  767.    } 
  768.   } 
  769.   // 加载config文件 
  770.   if (count($autoload['config']) > 0) 
  771.   { 
  772.    $CI =& get_instance(); 
  773.    foreach ($autoload['config'as $key => $val
  774.    { 
  775.     $CI->config->load($val); 
  776.    } 
  777.   } 
  778.   // 加载helper和language 
  779.   foreach (array('helper''language'as $type
  780.   { 
  781.    if (isset($autoload[$type]) AND count($autoload[$type]) > 0) 
  782.    { 
  783.     $this->$type($autoload[$type]); 
  784.    } 
  785.   } 
  786.   // 这个好像是为了兼容以前版本的 
  787.   if ( ! isset($autoload['libraries']) AND isset($autoload['core'])) 
  788.   { 
  789.    $autoload['libraries'] = $autoload['core']; 
  790.   } 
  791.   // 加载libraries 
  792.   if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0) 
  793.   { 
  794.    // 加载db 
  795.    if (in_array('database'$autoload['libraries'])) 
  796.    { 
  797.     $this->database(); 
  798.     $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); 
  799.    } 
  800.    // 加载所有其他libraries 
  801.    foreach ($autoload['libraries'as $item
  802.    { 
  803.     $this->library($item); 
  804.    } 
  805.   } 
  806.   // Autoload models 
  807.   if (isset($autoload['model'])) 
  808.   { 
  809.    $this->model($autoload['model']); 
  810.   } 
  811.  } 
  812.  // -------------------------------------------------------------------- 
  813.  /** 
  814.   * 返回由对象属性组成的关联数组 
  815.   */ 
  816.  protected function _ci_object_to_array($object
  817.  { 
  818.   return (is_object($object)) ? get_object_vars($object) : $object
  819.  } 
  820.  // -------------------------------------------------------------------- 
  821.  /** 
  822.   * 获取CI某个组件的实例 
  823.   */ 
  824.  protected function &_ci_get_component($component
  825.  { 
  826.   $CI =& get_instance(); 
  827.   return $CI->$component
  828.  } 
  829.  // -------------------------------------------------------------------- 
  830.  /** 
  831.   * 处理文件名,这个函数主要是返回正确文件名 
  832.   */ 
  833.  protected function _ci_prep_filename($filename$extension
  834.  { 
  835.   if ( ! is_array($filename)) 
  836.   { 
  837.    return array(strtolower(str_replace('.php'''str_replace($extension''$filename)).$extension)); 
  838.   } 
  839.   else 
  840.   { 
  841.    foreach ($filename as $key => $val
  842.    { 
  843.     $filename[$key] = strtolower(str_replace('.php'''str_replace($extension''$val)).$extension); 
  844.    }//www.phpfensi.com 
  845.    return $filename
  846.   } 
  847.  } 

Tags: CI框架装载器 Loader php

分享到: