PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载CI框架装载器Loader.
php源码分析,ciloader.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()复制代码代码如下:/*** Loader Class** 用户加载views和files,常见的函数有model(),view(),library(),helper()** Controller的好助手,$this->load =& load_class('Loader', 'core');,加载了loader,Controller就无比强大了*/ class CI_Loader {protected $_ci_ob_level;protected $_ci_view_paths = array();protected $_ci_library_paths = array();protected $_ci_model_paths = array();protected $_ci_helper_paths = array();protected $_base_classes = array(); // Set by the controller class protected $_ci_cached_vars = array();protected $_ci_classes = array();protected $_ci_loaded_files = array();protected $_ci_models = array();protected $_ci_helpers = array();protected $_ci_varmap = array('unit_test' => 'unit','user_agent' => 'agent');public function __construct(){//获取缓冲嵌套级别$this->_ci_ob_level = ob_get_level();//library路径$this->_ci_library_paths = array(APPPATH, BASEPATH);//helper路径$this->_ci_helper_paths = array(APPPATH, BASEPATH);//model路径$this->_ci_model_paths = array(APPPATH);//view路径$this->_ci_view_paths = array(APPPATH.'views/' => TRUE);log_message('debug', "Loader Class Initialized");}// --------------------------------------------------------------------/*** 初始化Loader**/ public function initialize(){$this->_ci_classes = array();$this->_ci_loaded_files = array();$this->_ci_models = array();//将is_loaded(common中记录加载核心类函数)加载的核心类交给_base_classes$this->_base_classes =& is_loaded();//加载autoload.php配置中文件$this->_ci_autoloader();return $this;}// --------------------------------------------------------------------/*** 检测类是否加载*/ public function is_loaded($class){if (isset($this->_ci_classes[$class])){return $this->_ci_classes[$class];}return FALSE;}// --------------------------------------------------------------------/*** 加载Class*/ public function library($library = '', $params = NULL, $object_name = NULL){if (is_array($library)){foreach ($library as $class){$this->library($class, $params);}return;}//如果$library为空或者已经加载。。。
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);}// --------------------------------------------------------------------/*** 加载和实例化model*/ public function model($model, $name = '', $db_conn = FALSE){//CI支持数组加载多个model if (is_array($model)){foreach ($model as $babe){$this->model($babe);}return;}if ($model == ''){return;}$path = '';// 是否存在子目录if (($last_slash = strrpos($model, '/')) !== FALSE){// The path is in front of the last slash$path = substr($model, 0, $last_slash + 1);// And the model name behind it$model = substr($model, $last_slash + 1);}if ($name == ''){$name = $model;}if (in_array($name, $this->_ci_models, TRUE)){return;}$CI =& get_instance();if (isset($CI->$name)){show_error('The model name you are loading is the name of a resource that is already being used: '.$name);}$model = strtolower($model); //model文件名全小写foreach ($this->_ci_model_paths as $mod_path){if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')){continue;}if ($db_conn !== FALSE AND ! class_exists('CI_DB')){if ($db_conn === TRUE){$db_conn = '';}$CI->load->database($db_conn, FALSE, TRUE);}if ( ! class_exists('CI_Model')){load_class('Model', 'core');}require_once($mod_path.'models/'.$path.$model.'.php');$model = ucfirst($model);$CI->$name = new $model();//保存在Loader::_ci_models中,以后可以用它来判断某个model是否已经加载过。
$this->_ci_models[] = $name;return;}// couldn't find the model show_error('Unable to locate the model you have specified: '.$model);}// --------------------------------------------------------------------/*** 数据库Loader*/ public function database($params = '', $return = FALSE, $active_record = NULL){// Grab the super object$CI =& get_instance();// 是否需要加载db if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db)){return FALSE;}require_once(BASEPATH.'database/DB.php');if ($return === TRUE){return DB($params, $active_record);}// Initialize the db variable. Needed to prevent// reference errors with some configurations$CI->db = '';// Load the DB class$CI->db =& DB($params, $active_record);}// --------------------------------------------------------------------/*** 加载数据库工具类*/ public function dbutil(){if ( ! class_exists('CI_DB')){$this->database();}$CI =& get_instance();// for backwards compatibility, load dbforge so we can extend dbutils off it// this use is deprecated and strongly discouraged$CI->load->dbforge();require_once(BASEPATH.'database/DB_utility.php');require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility.php');$class = 'CI_DB_'.$CI->db->dbdriver.'_utility';$CI->dbutil = new $class();}// --------------------------------------------------------------------/*** Load the Database Forge Class** @return string*/ public function dbforge(){if ( ! class_exists('CI_DB')){$this->database();}$CI =& get_instance();require_once(BASEPATH.'database/DB_forge.php');require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php');$class = 'CI_DB_'.$CI->db->dbdriver.'_forge';$CI->dbforge = new $class();}// --------------------------------------------------------------------/*** 加载视图文件*/ public function view($view, $vars = array(), $return = FALSE){return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));}// --------------------------------------------------------------------/*** 加载普通文件*/ public function file($path, $return = FALSE){return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));}// --------------------------------------------------------------------/*** 设置变量** Once variables are set they become available within* the controller class and its "view" files.
**/ public function vars($vars = array(), $val = ''){if ($val != '' AND is_string($vars)){$vars = array($vars => $val);}$vars = $this->_ci_object_to_array($vars);if (is_array($vars) AND count($vars) > 0){foreach ($vars as $key => $val){$this->_ci_cached_vars[$key] = $val;}}}// --------------------------------------------------------------------/*** 检查并获取变量*/ public function get_var($key){return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL;}// --------------------------------------------------------------------/*** 加载helper*/ public function helper($helpers = array()){foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper){if (isset($this->_ci_helpers[$helper])){continue;}$ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.'.php';// 如果是扩展helper的话if (file_exists($ext_helper)){$base_helper = BASEPATH.'helpers/'.$helper.'.php';if ( ! file_exists($base_helper)){show_error('Unable to load the requested file: helpers/'.$helper.'.php');}include_once($ext_helper);include_once($base_helper);$this->_ci_helpers[$helper] = TRUE;log_message('debug', 'Helper loaded: '.$helper);continue;}// 如果不是扩展helper,helper路径中加载helper foreach ($this->_ci_helper_paths as $path){if (file_exists($path.'helpers/'.$helper.'.php')){include_once($path.'helpers/'.$helper.'.php');$this->_ci_helpers[$helper] = TRUE;log_message('debug', 'Helper loaded: '.$helper);break;}}// 如果该helper还没加载成功的话,说明加载helper失败if ( ! isset($this->_ci_helpers[$helper])){show_error('Unable to load the requested file: helpers/'.$helper.'.php');}}}// --------------------------------------------------------------------/*** 可以看到helpers调用也是上面的helper,只是helpers的别名而已*/ public function helpers($helpers = array()){$this->helper($helpers);}// --------------------------------------------------------------------/*** 加载language文件*/ public function language($file = array(), $lang = ''){$CI =& get_instance();if ( ! is_array($file)){$file = array($file);}foreach ($file as $langfile){$CI->lang->load($langfile, $lang);}}// --------------------------------------------------------------------/*** 加载配置文件*/ public function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE){$CI =& get_instance();$CI->config->load($file, $use_sections, $fail_gracefully);}// --------------------------------------------------------------------/*** Driver** 加载 driver library*/ public function driver($library = '', $params = NULL, $object_name = NULL){if ( ! class_exists('CI_Driver_Library')){// we aren't instantiating an object here, that'll be done by the Library itself require BASEPATH.'libraries/Driver.php';}if ($library == ''){return FALSE;}// We can save the loader some time since Drivers will *always* be in a subfolder,// and typically identically named to the library if ( ! strpos($library, '/')){$library = ucfirst($library).'/'.$library;}return $this->library($library, $params, $object_name);}// --------------------------------------------------------------------/*** 添加 Package 路径** 把package路径添加到库,模型,助手,配置路径*/ public function add_package_path($path, $view_cascade=TRUE){$path = rtrim($path, '/').'/';array_unshift($this->_ci_library_paths, $path);array_unshift($this->_ci_model_paths, $path);array_unshift($this->_ci_helper_paths, $path);$this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;$config =& $this->_ci_get_component('config');array_unshift($config->_config_paths, $path);}// --------------------------------------------------------------------/*** 获取Package Paths,默认不包含BASEPATH*/ public function get_package_paths($include_base = FALSE){return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths;}// --------------------------------------------------------------------/*** 剔除Package Path** Remove a path from the library, model, and helper path arrays if it exists* If no path is provided, the most recently added path is removed.
**/ public function remove_package_path($path = '', $remove_config_path = TRUE){$config =& $this->_ci_get_component('config');if ($path == ''){$void = array_shift($this->_ci_library_paths);$void = array_shift($this->_ci_model_paths);$void = array_shift($this->_ci_helper_paths);$void = array_shift($this->_ci_view_paths);$void = array_shift($config->_config_paths);}else{$path = rtrim($path, '/').'/';foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var){if (($key = array_search($path, $this->{$var})) !== FALSE){unset($this->{$var}[$key]);}}if (isset($this->_ci_view_paths[$path.'views/'])){unset($this->_ci_view_paths[$path.'views/']);}if (($key = array_search($path, $config->_config_paths)) !== FALSE){unset($config->_config_paths[$key]);}}// 保证应用默认的路径依然存在$this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH)));$this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH)));$this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH)));$this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE));$config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH)));}// --------------------------------------------------------------------/*** Loader** This function is used to load views and files.
* Variables are prefixed with _ci_ to avoid symbol collision with* variables made available to view files** @param array* @return void*/ protected function _ci_load($_ci_data){// Set the default data variables foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val){$$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];}$file_exists = FALSE;//如果$_ci_path不为空,则说明当前要加载普通文件。Loader::file才会有path if ($_ci_path != ''){$_ci_x = explode('/', $_ci_path);$_ci_file = end($_ci_x);}else{$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);$_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view;foreach ($this->_ci_view_paths as $view_file => $cascade){if (file_exists($view_file.$_ci_file)){$_ci_path = $view_file.$_ci_file;$file_exists = TRUE;break;}if ( ! $cascade){break;}}}//view文件不存在则会报错if ( ! $file_exists && ! file_exists($_ci_path)){show_error('Unable to load the requested file: '.$_ci_file);}// 把CI的所有属性都传递给loader,view中$this指的是loader$_ci_CI =& get_instance();foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var){if ( ! isset($this->$_ci_key)){$this->$_ci_key =& $_ci_CI->$_ci_key;}}/** Extract and cache variables** You can either set variables using the dedicated $this->load_vars()* function or via the second parameter of this function. We'll merge* the two types and cache them so that views that are embedded within* other views can have access to these variables.
*/ if (is_array($_ci_vars)){$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);}extract($this->_ci_cached_vars);/** 将视图内容放到缓存区**/ ob_start();// 支持短标签if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE){echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('}else{include($_ci_path); // include() vs include_once() allows for multiple views with the same name}log_message('debug', 'File loaded: '.$_ci_path);// 是否直接返回view数据if ($_ci_return === TRUE){$buffer = ob_get_contents();@ob_end_clean();return $buffer;}//当前这个视图文件是被另一个视图文件通过$this->view()方法引入,即视图文件嵌入视图文件if (ob_get_level() > $this->_ci_ob_level + 1){ob_end_flush();}else{ ////把缓冲区的内容交给Output组件并清空关闭缓冲区。
$_ci_CI->output->append_output(ob_get_contents());@ob_end_clean();}}// --------------------------------------------------------------------/*** 加载类*/ protected function _ci_load_class($class, $params = NULL, $object_name = NULL){// 去掉.php和两端的/获取的$class就是类名或目录名+类名$class = str_replace('.php', '', trim($class, '/'));// CI允许dir/filename方式$subdir = '';if (($last_slash = strrpos($class, '/')) !== FALSE){// 目录$subdir = substr($class, 0, $last_slash + 1);// 文件名$class = substr($class, $last_slash + 1);}// 允许加载的类名首字母大写或全小写foreach (array(ucfirst($class), strtolower($class)) as $class){$subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php';// 是否是扩展类if (file_exists($subclass)){$baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php';if ( ! file_exists($baseclass)){log_message('error', "Unable to load the requested class: ".$class);show_error("Unable to load the requested class: ".$class);}// Safety: Was the class already loaded by a previous call?if (in_array($subclass, $this->_ci_loaded_files)){// Before we deem this to be a duplicate request, let's see// if a custom object name is being supplied. If so, we'll// return a new instance of the object if ( ! is_null($object_name)){$CI =& get_instance();if ( ! isset($CI->$object_name)){return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);}}$is_duplicate = TRUE;log_message('debug', $class." class already loaded. Second attempt ignored.");return;}include_once($baseclass);include_once($subclass);$this->_ci_loaded_files[] = $subclass;//实例化类return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);}// 如果不是扩展,和上面类似$is_duplicate = FALSE;foreach ($this->_ci_library_paths as $path){$filepath = $path.'libraries/'.$subdir.$class.'.php';// Does the file exist? No? Bummer...
if ( ! file_exists($filepath)){continue;}// Safety: Was the class already loaded by a previous call?if (in_array($filepath, $this->_ci_loaded_files)){// Before we deem this to be a duplicate request, let's see// if a custom object name is being supplied. If so, we'll// return a new instance of the object if ( ! is_null($object_name)){$CI =& get_instance();if ( ! isset($CI->$object_name)){return $this->_ci_init_class($class, '', $params, $object_name);}}$is_duplicate = TRUE;log_message('debug', $class." class already loaded. Second attempt ignored.");return;}include_once($filepath);$this->_ci_loaded_files[] = $filepath;return $this->_ci_init_class($class, '', $params, $object_name);}} // END FOREACH// 如果还没有找到该class,最后的尝试是该class会不会在同名的子目录下if ($subdir == ''){$path = strtolower($class).'/'.$class;return $this->_ci_load_class($path, $params);}// 加载失败,报错if ($is_duplicate == FALSE){log_message('error', "Unable to load the requested class: ".$class);show_error("Unable to load the requested class: ".$class);}}// --------------------------------------------------------------------/*** 实例化已经加载的类*/ protected function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL){// 是否有类的配置信息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)){// Break on the first found file, thus package files// are not overridden by default paths 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. Check for environment// first, global next if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')){include($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');break;}elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')){include($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');break;}elseif (file_exists($path .'config/'.strtolower($class).'.php')){include($path .'config/'.strtolower($class).'.php');break;}elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).'.php')){include($path .'config/'.ucfirst(strtolower($class)).'.php');break;}}}}if ($prefix == ''){ //system下library if (class_exists('CI_'.$class)){$name = 'CI_'.$class;}elseif (class_exists(config_item('subclass_prefix').$class)){ //扩展library$name = config_item('subclass_prefix').$class;}else{$name = $class;}}else{$name = $prefix.$class;}// Is the class name valid?if ( ! class_exists($name)){log_message('error', "Non-existent class: ".$name);show_error("Non-existent class: ".$class);}// Set the variable name we will assign the class to// Was a custom class name supplied? If so we'll use it$class = strtolower($class);if (is_null($object_name)){$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];}else{$classvar = $object_name;}// Save the class name and object name$this->_ci_classes[$class] = $classvar;// 将初始化的类的实例给CI超级句柄$CI =& get_instance();if ($config !== NULL){$CI->$classvar = new $name($config);}else{$CI->$classvar = new $name;}}// --------------------------------------------------------------------/*** 自动加载器** autoload.php配置的自动加载文件有:* | 1. Packages| 2. Libraries| 3. Helper files| 4. Custom config files| 5. Language files| 6. Models*/ private function _ci_autoloader(){if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')){include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');}else{include(APPPATH.'config/autoload.php');}if ( ! isset($autoload)){return FALSE;}// 自动加载packages,也就是将package_path加入到library,model,helper,config if (isset($autoload['packages'])){foreach ($autoload['packages'] as $package_path){$this->add_package_path($package_path);}}// 加载config文件if (count($autoload['config']) > 0){$CI =& get_instance();foreach ($autoload['config'] as $key => $val){$CI->config->load($val);}}// 加载helper和language foreach (array('helper', 'language') as $type){if (isset($autoload[$type]) AND count($autoload[$type]) > 0){$this->$type($autoload[$type]);}}// 这个好像是为了兼容以前版本的if ( ! isset($autoload['libraries']) AND isset($autoload['core'])){$autoload['libraries'] = $autoload['core'];}// 加载libraries if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0){// 加载db if (in_array('database', $autoload['libraries'])){$this->database();$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));}// 加载所有其他libraries foreach ($autoload['libraries'] as $item){$this->library($item);}}// Autoload models if (isset($autoload['model'])){$this->model($autoload['model']);}}// --------------------------------------------------------------------/*** 返回由对象属性组成的关联数组*/ protected function _ci_object_to_array($object){return (is_object($object)) ? get_object_vars($object) : $object;}// --------------------------------------------------------------------/*** 获取CI某个组件的实例*/ protected function &_ci_get_component($component){$CI =& get_instance();return $CI->$component;}// --------------------------------------------------------------------/*** 处理文件名,这个函数主要是返回正确文件名*/ protected function _ci_prep_filename($filename, $extension){if ( ! is_array($filename)){return array(strtolower(str_replace('.php', '', str_replace($extension, '', $filename)).$extension));}else{foreach ($filename as $key => $val){$filename[$key] = strtolower(str_replace('.php', '', str_replace($extension, '', $val)).$extension);}return $filename;}}}助ci框架怎更改默认的模板地址?
application/core/MY_Load.php MY_ 是前缀 在 application/config/config.php 的 $config['subclass_prefix'] = 'MY_'; 设置class MY_Loader extends CI_Loader{public function __construct(){parent::__construct();$this->_ci_view_paths = array(FCPATH.'/templates/'=> TRUE);}}//FCPATH 是和 application、system、index.php 同级的文件目录现在 在application 、system 同级目录 新建一个 templates目录 这个目录就是修改后的模版目录php CI框架里遇到的问题提示Fatal error: Class 'Test_model' not found in D:\wamp\www\CodeIgniter_2.1.2\system\core\Loader.php on line 303意思提示这个Test_model类找不到你的类名写错了,当然找不到了以下为model代码,文件名为test_model.php: (类名要与文件名保持一致才行)
class Test_m extends CI_Model{ // 最好要大写都大写改成test_model以下为contraller代码,文件名为user.php$this->load->model('test_model'); 它加载的时候找不到class test_model这样就应该能成功http://www.bkjia.com/PHPjc/906120.html www.bkjia.com true http://www.bkjia.com/PHPjc/906120.html TechArticle CI框架装载器Loader.php源码分析,ciloader.php 顾名思义,装载器就是加载元素的,使用ci时,经常加载的有: $this-load-library() $this-load-view() $t...
