内容简介:发现这个yredis没有load,怎么来的?翻翻手册,有自动加载配置在app/config/autoload.php中配置,部分内容如下
缘由
app/controllers/Index.php
中有如下代码
public function disable(){ $this->yredis->set('name','tb'); var_dump($this->yredis->get('name')); $this->load->view('welcome_message'); }
发现这个yredis没有load,怎么来的?翻翻手册,有自动加载配置
在app/config/autoload.php中配置,部分内容如下
| ------------------------------------------------------------------- | Auto-load Libraries | ------------------------------------------------------------------- | These are the classes located in system/libraries/ or your | application/libraries/ directory, with the addition of the | 'database' library, which is somewhat of a special case. | | Prototype: | | $autoload['libraries'] = array('database', 'email', 'session'); | | You can also supply an alternative library name to be assigned | in the controller: | | $autoload['libraries'] = array('user_agent' => 'ua'); */ $autoload['libraries'] = array('Yredis','validation'=>'sn');
追踪一下
那么他这个自动加载是在代码内如何实现的呢?肯定从头 $CI
大对象来看。
在 system/core/Controller.php中
,有如下两句
$this->load =& load_class('Loader', 'core'); $this->load->initialize();
通过 common.php
中定义的load_class方法,加载了loader类。不得不说ci的核心基本都在这里了。(这个load还是个未定义的属性么...?)
我们去看 system/core/Loader.php
中的initialize方法,不过load的时候肯定是先加载 __construct
方法
public function __construct() { // (ob机制,不要乱配~) $this->_ci_ob_level = ob_get_level(); $this->_ci_classes =& is_loaded(); log_message('info', 'Loader Class Initialized'); }
再回来看当前文件的initialize方法:
public function initialize() { $this->_ci_autoloader(); }
再去看_ci_autoloader...
protected function _ci_autoloader() { if (file_exists(APPPATH.'config/autoload.php')) { include(APPPATH.'config/autoload.php'); } if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')) { include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'); } if ( ! isset($autoload)) { return; } // Autoload packages if (isset($autoload['packages'])) { foreach ($autoload['packages'] as $package_path) { $this->add_package_path($package_path); } } // Load any custom config file if (count($autoload['config']) > 0) { foreach ($autoload['config'] as $val) { $this->config($val); } } // Autoload helpers and languages foreach (array('helper', 'language') as $type) { if (isset($autoload[$type]) && count($autoload[$type]) > 0) { $this->$type($autoload[$type]); } } // Autoload drivers if (isset($autoload['drivers'])) { $this->driver($autoload['drivers']); } // Load libraries if (isset($autoload['libraries']) && count($autoload['libraries']) > 0) { // Load the database driver. if (in_array('database', $autoload['libraries'])) { $this->database(); $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); } // Load all other libraries $this->library($autoload['libraries']); } // Autoload models if (isset($autoload['model'])) { $this->model($autoload['model']); } }
这里总算有点眉目,定位到了加载开头配置的 autoload.php
的位置,
include(APPPATH.'config/autoload.php')
;
不难得出,是分别处理配置段的 packages,config,helper,language,dirvers,libraries
(包含database在内),我们只是看library,于是定位到
$this->library($autoload['libraries']);
这里,看library方法
public function library($library, $params = NULL, $object_name = NULL) { if (empty($library)) { return $this; } elseif (is_array($library)) { foreach ($library as $key => $value) { if (is_int($key)) { $this->library($value, $params); } else { $this->library($key, $params, $value); } } return $this; } if ($params !== NULL && ! is_array($params)) { $params = NULL; } $this->_ci_load_library($library, $params, $object_name); return $this; }
froeach中的if else 就是判断是否使用了别名,就像开头在 autoload.php
中配置
$autoload['libraries'] = array('Yredis','validation'=>'sn')
;的第二个参数那样,这样我们在项目中可以显示使用 $this->sn->xx()
执行了。当然到这还没完,虽然最后返回的是 $this
,但是之前执行了关键的一步
$this->_ci_load_library($library, $params, $object_name);
我们继续看 _ci_load_library
方法
protected function _ci_load_library($class, $params = NULL, $object_name = NULL) { // Get the class name, and while we're at it trim any slashes. // The directory path can be included as part of the class name, // but we don't want a leading slash $class = str_replace('.php', '', trim($class, '/')); // Was the path included with the class name? // We look for a slash to determine this if (($last_slash = strrpos($class, '/')) !== FALSE) { // Extract the path $subdir = substr($class, 0, ++$last_slash); // Get the filename from the path $class = substr($class, $last_slash); } else { $subdir = ''; } $class = ucfirst($class); // Is this a stock library? There are a few special conditions if so ... if (file_exists(BASEPATH.'libraries/'.$subdir.$class.'.php')) { return $this->_ci_load_stock_library($class, $subdir, $params, $object_name); } // Safety: Was the class already loaded by a previous call? if (class_exists($class, FALSE)) { $property = $object_name; if (empty($property)) { $property = strtolower($class); isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property]; } $CI =& get_instance(); if (isset($CI->$property)) { log_message('debug', $class.' class already loaded. Second attempt ignored.'); return; } return $this->_ci_init_library($class, '', $params, $object_name); } // Let's search for the requested library file and load it. foreach ($this->_ci_library_paths as $path) { // BASEPATH has already been checked for if ($path === BASEPATH) { continue; } $filepath = $path.'libraries/'.$subdir.$class.'.php'; // Does the file exist? No? Bummer... if ( ! file_exists($filepath)) { continue; } include_once($filepath); return $this->_ci_init_library($class, '', $params, $object_name); } // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified? if ($subdir === '') { return $this->_ci_load_library($class.'/'.$class, $params, $object_name); } // If we got this far we were unable to find the requested class. log_message('error', 'Unable to load the requested class: '.$class); show_error('Unable to load the requested class: '.$class); }
大家可以看多个return的前导条件,我们最后追到 _ci_init_library
方法。如下:
protected function _ci_init_library($class, $prefix, $config = FALSE, $object_name = NULL) { // Is there an associated config file for this class? Note: these should always be lowercase if ($config === NULL) { // Fetch the config paths containing any package paths $config_component = $this->_ci_get_component('config'); if (is_array($config_component->_config_paths)) { $found = FALSE; foreach ($config_component->_config_paths as $path) { // We test for both uppercase and lowercase, for servers that // are case-sensitive with regard to file names. Load global first, // override with environment next if (file_exists($path.'config/'.strtolower($class).'.php')) { include($path.'config/'.strtolower($class).'.php'); $found = TRUE; } elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php')) { include($path.'config/'.ucfirst(strtolower($class)).'.php'); $found = TRUE; } if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')) { include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'); $found = TRUE; } elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')) { include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'); $found = TRUE; } // Break on the first found configuration, thus package // files are not overridden by default paths if ($found === TRUE) { break; } } } } $class_name = $prefix.$class; // Is the class name valid? if ( ! class_exists($class_name, FALSE)) { log_message('error', 'Non-existent class: '.$class_name); show_error('Non-existent class: '.$class_name); } // Set the variable name we will assign the class to // Was a custom class name supplied? If so we'll use it if (empty($object_name)) { $object_name = strtolower($class); if (isset($this->_ci_varmap[$object_name])) { $object_name = $this->_ci_varmap[$object_name]; } } // Don't overwrite existing properties $CI =& get_instance(); if (isset($CI->$object_name)) { if ($CI->$object_name instanceof $class_name) { log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted."); return; } show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance."); } // Save the class name and object name $this->_ci_classes[$object_name] = $class; var_dump($class); // Instantiate the class $CI->$object_name = isset($config) ? new $class_name($config) : new $class_name(); }
注意多条件下的大小写处理( strtolower
, ucfirst
),等想出坑(如果有)的时候别忘记这里就好。走到最后就是这关键货
$CI->$object_name = isset($config) ? new $class_name($config) : new $class_name();
到这里就很清楚了,最后参考CI大对象,输出部分如下
//... ["load"]=> &object(Api_Loader)#13 (12) { ["_ci_services_paths":protected]=> array(1) { [0]=> string(45) "/usr/share/nginx/xin_mount_dev/trunk/app/" } ["_ci_services":protected]=> array(0) { } ["_ci_ob_level":protected]=> int(1) ["_ci_view_paths":protected]=> array(1) { ["/usr/share/nginx/xin_mount_dev/trunk/app/views/"]=> bool(true) } ["_ci_library_paths":protected]=> array(2) { [0]=> string(45) "/usr/share/nginx/xin_mount_dev/trunk/app/" [1]=> string(24) "/usr/share/nginx/ci_3.0/" } ["_ci_model_paths":protected]=> array(1) { [0]=> string(45) "/usr/share/nginx/xin_mount_dev/trunk/app/" } ["_ci_helper_paths":protected]=> array(2) { [0]=> string(45) "/usr/share/nginx/xin_mount_dev/trunk/app/" [1]=> string(24) "/usr/share/nginx/ci_3.0/" } ["_ci_cached_vars":protected]=> array(0) { } ["_ci_classes":protected]=> &array(15) { ["benchmark"]=> string(9) "Benchmark" ["hooks"]=> string(5) "Hooks" ["config"]=> string(6) "Config" ["log"]=> string(3) "Log" ["utf8"]=> string(4) "Utf8" ["uri"]=> string(3) "URI" ["router"]=> string(6) "Router" ["output"]=> string(6) "Output" ["security"]=> string(8) "Security" ["input"]=> string(5) "Input" ["lang"]=> string(4) "Lang" ["loader"]=> string(6) "Loader" ["yredis"]=> string(6) "Yredis" ["sn"]=> string(10) "Validation" } ["_ci_models":protected]=> array(0) { } ["_ci_helpers":protected]=> array(0) { } ["_ci_varmap":protected]=> array(2) { ["unit_test"]=> string(4) "unit" ["user_agent"]=> string(5) "agent" } } ["yredis"]=> object(Yredis)#14 (2) { ["_redis":"Yredis":private]=> object(Redis)#15 (0) { } ["_redis_conf":"Yredis":private]=> array(2) { ["hostname"]=> string(9) "127.0.0.1" ["port"]=> string(4) "6379" } } ["sn"]=> object(Validation)#16 (6) // ...
关注yredis和sn就更清楚啦,注意sn是别名,而实际指向的是Validation这个类
结束
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Git命令别名设置
- mybatis的typeAliases别名
- Elasticsearch基础但非常有用的功能之一:别名
- Elasticsearch索引的基本操作(5)-别名设置
- Elasticsearch 技术分析(三): 索引别名Aliases问题
- c++ 这是否真的破坏了严格的别名规则?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
删除
[英] 维克托•迈尔-舍恩伯格(Viktor Mayer-Schönberger)著 / 袁杰 译 / 浙江人民出版社 / 2013-1 / 49.90元
《删除》讲述了遗忘的美德,为读者展现了大数据时代的取舍之道。 《删除》从大数据时代信息取舍的目的和方法分别诠释了“被遗忘的权利”。维克托首先回溯了人类追寻记忆的过程,之后提出数字技术与全球网络正在瓦解我们天生的遗忘能力。对此,他考察了促进遗忘终止4大驱动力——数字化,廉价的存储器,易于提取,全球性访问。之后,他提出了当前数字化记忆的两大威胁——信息权力与时间,并给出了应对威胁的6大对策——数......一起来看看 《删除》 这本书的介绍吧!