CI框架 -- 核心文件 之 Loader.php(加载器)

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

加载类库文件:$this->load->library()

加载视图文件:$this->load->view()

加载模型文件:$this->load->model()

加载数据库文件:$this->load->database()

加载帮助文件:$this->load->helper()

加载配置文件:$this->load->config()

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

时间: 2024-10-07 03:20:50

CI框架 -- 核心文件 之 Loader.php(加载器)的相关文章

CI框架 -- 核心文件 之 Lang.php(加载语言包)

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class CI_Lang { var $language = array(); var $is_loaded = array(); function __construct() { log_message('debug', "Language Class Initialized"); } //加载语言包 function load

CI框架 -- 核心文件 之 Hooks.php

CI框架可以实现在不修改系统核心文件的基础上来改变或增加系统的核心运行功能,那就是Hook,看看CI有哪些钩子: pre_system系统执行的早期调用.仅仅在benchmark 和 hooks 类 加载完毕的时候. 没有执行路由或者其它的过程. pre_controller在调用你的任何控制器之前调用.此时所用的基础类,路由选择和安全性检查都已完成. post_controller_constructor在你的控制器实例化之后,任何方法调用之前调用. post_controller在你的控制器

CI框架 -- 核心文件 之 Input.php(输入数据处理文件)

class CI_Input { //用户ip地址 protected $ip_address = FALSE; //用户浏览器地址 protected $user_agent = FALSE; //允许get方式提交数据 protected $_allow_get_array = TRUE; //新行央视标记 protected $_standardize_newlines = TRUE; //xss攻击过滤 protected $_enable_xss = FALSE; //csrf攻击过滤

vue-loader 配置了css加载器属性。

module: { loaders: [ // 这里也是相应的配置,test就是匹配文件,loader是加载器, { test: /\.vue$/, loader: 'vue' }, { test: /\.js$/, loader: 'babel', include: projectRoot, exclude: /node_modules/ }, { test: /\.json$/, loader: 'json' }, /* { test: /\.css$/, //这是注释掉的模块,一开始很疑惑

webpack loader加载器

配置loader,通过加载器处理文件,例如css sass less等,告诉webpack每一种文件都需要使用什么来加载器来处理. 1.node.js安装好之后也会自动默认安装好npm,所以cmd cd进入当前项目下输入npm install babel-loader babel babel-core css-loader style-loader url-loader file-loader less-loader less --save-dev命令下载这些包. 2.修改webpack.con

15.资源加载器,根据配置文件自动加载文件

前言 以前我想自己写一个加载器,用的时候加载,不用的时候再去掉,结果发现这种方式可能因为资源不统一在安卓上可能出现问题,所以搜集资料,弄成根据配置文件加载 思路 设定两个配置文件,screen,res,不同场景对应不同的screen,不同screen使用的资源为res,当切换的screen的res相同时,不对资源处理,直接切换,否则进入load场景等待资源加载和卸载,然后再跳转场景 下图为场景screen配置文件和资源res配置文件,screen配置了加载的背景图(bgImage),随后做配置化

实现简单的 JS 模块加载器

实现简单的 JS 模块加载器 按需加载是前端性能优化的一个重要手段,按需加载的本质是从远程服务器加载一段JS代码(这里主要讨论JS,CSS或者其他资源大同小异),该JS代码就是一个模块的定义,如果您之前有去思考过按需加载的原理,那你可能已经知道按需加载需要依赖一个模块加载器.它可以加载所有的静态资源文件,比如: JS 脚本 CSS? 脚本 图片 资源 如果你了解 webpack,那您可以发现在 webpack 内部,它实现了一个模块加载器.模块加载器本身需要遵循一个规范,当然您可以自定义规范,大

一步步手动实现热修复(一)-dex文件的生成与加载

热修复技术自从QQ空间团队搞出来之后便渐渐趋于成熟. 我们这个系列主要介绍如何一步步手动实现基本的热修复功能,无需使用第三方框架. 在开始学习之前,需要对基本的热修复技术有些了解,以下文章可以帮助到你: 安卓App热补丁动态修复技术介绍 [腾讯Bugly干货分享]Android Patch 方案与持续交付 Android dex分包方案 dodola/HotFix dex文件的生成与加载 我们在这部分主要做的流程有: 1.编写基本的Java文件并编译为.class文件. 2.将.class文件转

asp.net使用httphandler打包多CSS或JS文件以加快页面加载速度

介绍 使用许多小得JS.CSS文件代替一个庞大的JS或CSS文件来让代码获得更好的可维 护性,这是一个很好的实践.但这样做反过来却损失了网站的性能.虽然你应该将你的Javascript代码写在小文件中并且将大的CSS文件分割到小文件 中,当一个浏览器请求那些JS以及CSS文件,它却将为每一个文件产生一个请求.每一个HTTP请求将导致从你的浏览器到服务器上的一次"往返",从响应 服务器到客户端浏览器之间的等待时间称之为"延时".因此,如果你有四个JS文件以及三个CSS