I was bored, so I decided to give it a try.
CI (CodeIgniter) is the first framework I came into contact with, and so far I have only used some fragmentary methods. I have always wanted to make a summary of its process, but I always get stuck on it for various "reasons". When I see other people’s diagrams coming together, I don’t have the patience, so let’s start with the code, just as a note to commemorate.
Looking at the online user manual, you also know that download the CI (the latest version 2.2.1) and unzip it to the machine, such as the www directory, you can change the root directory name (the original name CodeIgniter-2.2-stable is too long), The preliminary directory files are as follows, of course this is under windows.
After accessing, such as localhost/ci/index.php, you will enter the CI default Welcome page
How to load this page step by step? The first thing to access is the index.php script
1 php 2 3 /* 4 *--------------------------------------------------------------- 5 * APPLICATION ENVIRONMENT 6 *--------------------------------------------------------------- 7 * 8 * You can load different configurations depending on your 9 * current environment. Setting the environment also influences 10 * things like logging and error reporting. 11 * 12 * This can be set to anything, but default usage is: 13 * 14 * development 15 * testing 16 * production 17 * 18 * NOTE: If you change these, also change the error_reporting() code below 19 * 20 */ 21 define('ENVIRONMENT', 'development'); 22 /* 23 *--------------------------------------------------------------- 24 * ERROR REPORTING 25 *--------------------------------------------------------------- 26 * 27 * Different environments will require different levels of error reporting. 28 * By default development will show errors but testing and live will hide them. 29 */ 30 31 if (defined('ENVIRONMENT')) 32 { 33 switch (ENVIRONMENT) 34 { 35 case 'development': 36 error_reporting(E_ALL); 37 break; 38 39 case 'testing': 40 case 'production': 41 error_reporting(0); 42 break; 43 44 default: 45 exit('The application environment is not set correctly.'); 46 } 47 } 48 49 /* 50 *--------------------------------------------------------------- 51 * SYSTEM FOLDER NAME 52 *--------------------------------------------------------------- 53 * 54 * This variable must contain the name of your "system" folder. 55 * Include the path if the folder is not in the same directory 56 * as this file. 57 * 58 */ 59 $system_path = 'system'; 60 61 /* 62 *--------------------------------------------------------------- 63 * APPLICATION FOLDER NAME 64 *--------------------------------------------------------------- 65 * 66 * If you want this front controller to use a different "application" 67 * folder then the default one you can set its name here. The folder 68 * can also be renamed or relocated anywhere on your server. If 69 * you do, use a full server path. For more info please see the user guide: 70 * http://codeigniter.com/user_guide/general/managing_apps.html 71 * 72 * NO TRAILING SLASH! 73 * 74 */ 75 $application_folder = 'application'; 76 77 /* 78 * -------------------------------------------------------------------- 79 * DEFAULT CONTROLLER 80 * -------------------------------------------------------------------- 81 * 82 * Normally you will set your default controller in the routes.php file. 83 * You can, however, force a custom routing by hard-coding a 84 * specific controller class/function here. For most applications, you 85 * WILL NOT set your routing here, but it's an option for those 86 * special instances where you might want to override the standard 87 * routing in a specific front controller that shares a common CI installation. 88 * 89 * IMPORTANT: If you set the routing here, NO OTHER controller will be 90 * callable. In essence, this preference limits your application to ONE 91 * specific controller. Leave the function name blank if you need 92 * to call functions dynamically via the URI. 93 * 94 * Un-comment the $routing array below to use this feature 95 * 96 */ 97 // The directory name, relative to the "controllers" folder. Leave blank 98 // if your controller is not in a sub-folder within the "controllers" folder 99 // $routing['directory'] = ''; 100 101 // The controller class file name. Example: Mycontroller 102 // $routing['controller'] = ''; 103 104 // The controller function you wish to be called. 105 // $routing['function'] = ''; 106 107 108 /* 109 * ------------------------------------------------------------------- 110 * CUSTOM CONFIG VALUES 111 * ------------------------------------------------------------------- 112 * 113 * The $assign_to_config array below will be passed dynamically to the 114 * config class when initialized. This allows you to set custom config 115 * items or override any default config values found in the config.php file. 116 * This can be handy as it permits you to share one application between 117 * multiple front controller files, with each file containing different 118 * config values. 119 * 120 * Un-comment the $assign_to_config array below to use this feature 121 * 122 */ 123 // $assign_to_config['name_of_config_item'] = 'value of config item'; 124 125 126 127 // -------------------------------------------------------------------- 128 // END OF USER CONFIGURABLE SETTINGS. DO NOT EDIT BELOW THIS LINE 129 // -------------------------------------------------------------------- 130 131 /* 132 * --------------------------------------------------------------- 133 * Resolve the system path for increased reliability 134 * --------------------------------------------------------------- 135 */ 136 137 // Set the current directory correctly for CLI requests 138 if (defined('STDIN')) 139 { 140 chdir(dirname(__FILE__)); 141 } 142 143 if (realpath($system_path) !== FALSE) 144 { 145 $system_path = realpath($system_path).'/'; 146 } 147 148 // ensure there's a trailing slash 149 $system_path = rtrim($system_path, '/').'/'; 150 151 // Is the system path correct? 152 if ( ! is_dir($system_path)) 153 { 154 exit("Your system folder path does not appear to be set correctly. Please open the following file and correct this: ".pathinfo(__FILE__, PATHINFO_BASENAME)); 155 } 156 157 /* 158 * ------------------------------------------------------------------- 159 * Now that we know the path, set the main path constants 160 * ------------------------------------------------------------------- 161 */ 162 // The name of THIS file 163 define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME)); 164 165 // The PHP file extension 166 // this global constant is deprecated. 167 define('EXT', '.php'); 168 169 // Path to the system folder 170 define('BASEPATH', str_replace("\", "/", $system_path)); 171 172 // Path to the front controller (this file) 173 define('FCPATH', str_replace(SELF, '', __FILE__)); 174 175 // Name of the "system folder" 176 define('SYSDIR', trim(strrchr(trim(BASEPATH, '/'), '/'), '/')); 177 178 179 // The path to the "application" folder 180 if (is_dir($application_folder)) 181 { 182 define('APPPATH', $application_folder.'/'); 183 } 184 else 185 { 186 if ( ! is_dir(BASEPATH.$application_folder.'/')) 187 { 188 exit("Your application folder path does not appear to be set correctly. Please open the following file and correct this: ".SELF); 189 } 190 191 define('APPPATH', BASEPATH.$application_folder.'/'); 192 }193 194 /* 195 * --------------------------------------------- -------------------------- 196 * LOAD THE BOOTSTRAP FILE 197 * ------------------------------------ -------------------------------- 198 * 199 * And away we go... 200 * 201 */ 202 require_once BASEPATH.'core/CodeIgniter.php'; 203 204 /* End of file index.php */ 205 /* Location: ./index.php */ View CodeLine 21: First define an ENVIRONMENT constant as development, which is the development environment.
Lines 31-47: switch statement. Since the current environment is development, it is set to report all levels of errors.
Lines 49-59: The $system_path variable defines the default system script directory of CI as system, and lines 61-75 define the current default directory for our main development as application.
Lines 77-105: All commented out, here is where we can force the default directory name ($routing['directory']), controller name ($routing['directory']) and method when the system is loaded. name ($routing['directory']), although generally these are set in applicationconfigroutes.php (picture below), the Welcome page accessed is also through this default controller Welcome class, this is only as a selective method, Actually there is no need to do it
Lines 108-129: All commented out, used for custom configuration variables (CUSTOM CONFIG VALUES). As mentioned in the previous article, there is always some configuration information in any back-end project, but the loading methods of each project or framework are different. This $assign_to_config array stores our custom configuration information, such as $assign_to_config['home'] = 'localhost';. The reason why it is commented out is because this is only an optional operation. The user-defined configuration information of CI , usually placed under the applicationconfig directory, with automatic loading information (autoload.php), general configuration information (config.php), constants (constants.php), database (database.php) and other separate files stored, so it is generally not in Here to configure a variable to be used, $assign_to_config is not defined by default.
From line 131 to the end of the index.php file are mainly the definitions of some path variables.
Lines 137-141: It is prepared for the CLI (Command-Interface Line) calling method. It runs the script directly through the terminal command on the Mac/Linux system. This is on the CI Chinese official website (http://codeigniter.org .cn/user_guide/general/cli.html) is also introduced. If a constant named STDIN is defined, the execution directory will be changed to the directory where the current file is located. Of course, the definition of the constant STDIN has not appeared before, so it will not be executed here. .
Lines 143-155: Determine the directory variable $system_path where the framework stores system scripts, which is the system directory in the previous figure. Its validity will be tested here. If it is invalid, the program will hang here.
Lines 157-192: Define several main directory constants, namely SELF: file name of the current script, EXT: script extension, BASEPATH: path to the system directory, FCPATH: directory where the current script is located, SYSDIR: system directory The directory name, if not changed, is system.
Lines 179-194: Define the APPPATH constant and determine the directory where the application is located, which is where we will mainly develop in the future. Use is_dir to detect it. Note that is_dir can detect relative directories, so what is actually run is the code in if. APPPATH gets the relative path.
Finally, print to see what the values of these variables (constants) are, some of which are related to the storage directory:
Line 202: Load the BASEPATH.'core/CodeIgniter.php' script, which is the file in the core class file directory under the system directory and enters the file in the core class directory of CI.
================================================== ================================================== ====
1 if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 2 /** 3 * CodeIgniter 4 * 5 * An open source application development framework for PHP 5.1.6 or newer 6 * 7 * @package CodeIgniter 8 * @author EllisLab Dev Team 9 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. 10 * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/) 11 * @license http://codeigniter.com/user_guide/license.html 12 * @link http://codeigniter.com 13 * @since Version 1.0 14 * @filesource 15 */ 16 17 // ------------------------------------------------------------------------ 18 19 /** 20 * System Initialization File 21 * 22 * Loads the base classes and executes the request. 23 * 24 * @package CodeIgniter 25 * @subpackage codeigniter 26 * @category Front-controller 27 * @author EllisLab Dev Team 28 * @link http://codeigniter.com/user_guide/ 29 */ 30 31 /** 32 * CodeIgniter Version 33 * 34 * @var string 35 * 36 */ 37 define('CI_VERSION', '2.2.1'); 38 39 /** 40 * CodeIgniter Branch (Core = TRUE, Reactor = FALSE) 41 * 42 * @var boolean 43 * 44 */ 45 define('CI_CORE', FALSE); 46 47 /* 48 * ------------------------------------------------------ 49 * Load the global functions 50 * ------------------------------------------------------ 51 */ 52 require(BASEPATH.'core/Common.php'); 53 54 /* 55 * ------------------------------------------------------ 56 * Load the framework constants 57 * ------------------------------------------------------ 58 */ 59 if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php')) 60 { 61 require(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); 62 } 63 else 64 { 65 require(APPPATH.'config/constants.php'); 66 } 67 68 /* 69 * ------------------------------------------------------ 70 * Define a custom error handler so we can log PHP errors 71 * ------------------------------------------------------ 72 */ 73 set_error_handler('_exception_handler'); 74 75 if ( ! is_php('5.3')) 76 { 77 @set_magic_quotes_runtime(0); // Kill magic quotes 78 } 79 80 /* 81 * ------------------------------------------------------ 82 * Set the subclass_prefix 83 * ------------------------------------------------------ 84 * 85 * Normally the "subclass_prefix" is set in the config file. 86 * The subclass prefix allows CI to know if a core class is 87 * being extended via a library in the local application 88 * "libraries" folder. Since CI allows config items to be 89 * overriden via data set in the main index. php file, 90 * before proceeding we need to know if a subclass_prefix 91 * override exists. If so, we will set this value now, 92 * before any classes are loaded 93 * Note: Since the config file data is cached it doesn't 94 * hurt to load it here. 95 */ 96 if (isset($assign_to_config['subclass_prefix']) AND $assign_to_config['subclass_prefix'] != '') 97 { 98 get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix'])); 99 } 100 101 /* 102 * ------------------------------------------------------ 103 * Set a liberal script execution time limit 104 * ------------------------------------------------------ 105 */ 106 if (function_exists("set_time_limit") == TRUE AND @ini_get("safe_mode") == 0) 107 { 108 @set_time_limit(300); 109 } 110 111 /* 112 * ------------------------------------------------------ 113 * Start the timer... tick tock tick tock... 114 * ------------------------------------------------------ 115 */ 116 $BM =& load_class('Benchmark', 'core'); 117 $BM->mark('total_execution_time_start'); 118 $BM->mark('loading_time:_base_classes_start'); 119 120 /* 121 * ------------------------------------------------------ 122 * Instantiate the hooks class 123 * ------------------------------------------------------ 124 */ 125 $EXT =& load_class('Hooks', 'core'); 126 127 /* 128 * ------------------------------------------------------ 129 * Is there a "pre_system" hook? 130 * ------------------------------------------------------ 131 */ 132 $EXT->_call_hook('pre_system'); 133 134 /* 135 * ------------------------------------------------------ 136 * Instantiate the config class 137 * ------------------------------------------------------ 138 */ 139 $CFG =& load_class('Config', 'core'); 140 141 // Do we have any manually set config items in the index.php file? 142 if (isset($assign_to_config)) 143 { 144 $CFG->_assign_to_config($assign_to_config); 145 }146 147 /* 148 * ------------------------------------------------------ 149 * Instantiate the UTF-8 class 150 * ------------------------------------------------------ 151 * 152 * Note: Order here is rather important as the UTF-8 153 * class needs to be used very early on, but it cannot 154 * properly determine if UTf-8 can be supported until 155 * after the Config class is instantiated. 156 * 157 */ 158 159 $UNI =& load_class('Utf8', 'core'); 160 161 /* 162 * ------------------------------------------------------ 163 * Instantiate the URI class 164 * ------------------------------------------------------ 165 */ 166 $URI =& load_class('URI', 'core'); 167 168 /* 169 * ------------------------------------------------------ 170 * Instantiate the routing class and set the routing 171 * ------------------------------------------------------ 172 */ 173 $RTR =& load_class('Router', 'core'); 174 $RTR->_set_routing(); 175 176 // Set any routing overrides that may exist in the main index file 177 if (isset($routing)) 178 { 179 $RTR->_set_overrides($routing); 180 } 181 182 /* 183 * ------------------------------------------------------ 184 * Instantiate the output class 185 * ------------------------------------------------------ 186 */ 187 $OUT =& load_class('Output', 'core'); 188 189 /* 190 * ------------------------------------------------------ 191 * Is there a valid cache file? If so, we're done... 192 * ------------------------------------------------------ 193 */ 194 if ($EXT->_call_hook('cache_override') === FALSE) 195 { 196 if ($OUT->_display_cache($CFG, $URI) == TRUE) 197 { 198 exit; 199 } 200 }201 202 /* 203 * ----------------------------------------------------- 204 * Load the security class for xss and csrf support 205 * ----------------------------------------------------- 206 */ 207 $SEC =& load_class('Security', 'core'); 208 209 /* 210 * ------------------------------------------------------ 211 * Load the Input class and sanitize globals 212 * ------------------------------------------------------ 213 */ 214 $IN =& load_class('Input', 'core'); 215 216 /* 217 * ------------------------------------------------------ 218 * Load the Language class 219 * ------------------------------------------------------ 220 */ 221 $LANG =& load_class('Lang', 'core'); 222 223 /* 224 * ------------------------------------------------------ 225 * Load the app controller and local controller 226 * ------------------------------------------------------ 227 * 228 */ 229 // Load the base controller class 230 require BASEPATH.'core/Controller.php'; 231 232 function &get_instance() 233 { 234 return CI_Controller::get_instance(); 235 } 236 237 238 if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php')) 239 { 240 require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'; 241 } 242 243 // Load the local application controller 244 // Note: The Router class automatically validates the controller path using the router->_validate_request(). 245 // If this include fails it means that the default controller in the Routes.php file is not resolving to something valid. 246 if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php')) 247 { 248 show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.'); 249 }250 251 include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php'); 252 253 // Set a mark point for benchmarking 254 $BM->mark('loading_time:_base_classes_end'); 255 256 /* 257 * ------------------------------------------------------ 258 * Security check 259 * ------------------------------------------------------ 260 * 261 * None of the functions in the app controller or the 262 * loader class can be called via the URI, nor can 263 * controller functions that begin with an underscore 264 */ 265 $class = $RTR->fetch_class(); 266 $method = $RTR->fetch_method(); 267 268 if ( ! class_exists($class) 269 OR strncmp($method, '_', 1) == 0 270 OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller'))) 271 ) 272 { 273 if ( ! empty($RTR->routes['404_override'])) 274 { 275 $x = explode('/', $RTR->routes['404_override']); 276 $class = $x[0]; 277 $method = (isset($x[1]) ? $x[1] : 'index'); 278 if ( ! class_exists($class)) 279 { 280 if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) 281 { 282 show_404("{$class}/{$method}"); 283 } 284 285 include_once(APPPATH.'controllers/'.$class.'.php'); 286 } 287 } 288 else 289 { 290 show_404("{$class}/{$method}"); 291 } 292 }293 294 /* 295 * ------------------------------------------------------ 296 * Is there a "pre_controller" hook? 297 * ------------------------------------------------------ 298 */ 299 $EXT->_call_hook('pre_controller'); 300 301 /* 302 * ------------------------------------------------------ 303 * Instantiate the requested controller 304 * ------------------------------------------------------ 305 */ 306 // Mark a start point so we can benchmark the controller 307 $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start'); 308 309 $CI = new $class(); 310 311 /* 312 * ------------------------------------------------------ 313 * Is there a "post_controller_constructor" hook? 314 * ------------------------------------------------------ 315 */ 316 $EXT->_call_hook('post_controller_constructor'); 317 318 /* 319 * ------------------------------------------------------ 320 * Call the requested method 321 * ------------------------------------------------------ 322 */ 323 // Is there a "remap" function? If so, we call it instead 324 if (method_exists($CI, '_remap')) 325 { 326 $CI->_remap($method, array_slice($URI->rsegments, 2)); 327 } 328 else 329 { 330 // is_callable() returns TRUE on some versions of PHP 5 for private and protected 331 // methods, so we'll use this workaround for consistent behavior 332 if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI)))) 333 { 334 // Check and see if we are using a 404 override and use it. 335 if ( ! empty($RTR->routes['404_override'])) 336 { 337 $x = explode('/', $RTR->routes['404_override']); 338 $class = $x[0]; 339 $method = (isset($x[1]) ? $x[1] : 'index'); 340 if ( ! class_exists($class)) 341 { 342 if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) 343 { 344 show_404("{$class}/{$method}"); 345 } 346 347 include_once(APPPATH.'controllers/'.$class.'.php'); 348 unset($CI); 349 $CI = new $class(); 350 } 351 } 352 else 353 { 354 show_404("{$class}/{$method}"); 355 } 356 }357 358 // Call the requested method. 359 // Any URI segments present (besides the class/function) will be passed to the method for convenience 360 call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2)); 361 } 362 363 364 // Mark a benchmark end point 365 $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end'); 366 367 /* 368 * ------------------------------------------------------ 369 * Is there a "post_controller" hook? 370 * ------------------------------------------------------ 371 */ 372 $EXT->_call_hook('post_controller'); 373 374 /* 375 * ------------------------------------------------------ 376 * Send the final rendered output to the browser 377 * ------------------------------------------------------ 378 */ 379 if ($EXT->_call_hook('display_override') === FALSE) 380 { 381 $OUT->_display(); 382 } 383 384 /* 385 * ------------------------------------------------------ 386 * Is there a "post_system" hook? 387 * ------------------------------------------------------ 388 */ 389 $EXT->_call_hook('post_system'); 390 391 /* 392 * ------------------------------------------------------ 393 * Close the DB connection if one exists 394 * ------------------------------------------------------ 395 */ 396 if (class_exists('CI_DB') AND isset($CI->db)) 397 { 398 $CI->db->close(); 399 } 400 401 402 /* End of file CodeIgniter.php */ 403 /* Location: ./system/core/CodeIgniter.php */ View Code在CodeIgniter中,可以看到开头的英文描述,该脚本时系统初始化文件,主要作用是装载基类和执行请求。
31-45行:定义了CI_VERSION常量,描述当前框架版本,CI_CORE常量,目前我也不清楚没探究过,注释是CI的分支,啥意思?
52行:加载系统核心目录下的Common.php文件,Load the global functions,记得前一篇中说到,一般一个项目会将很多公共方法放在一个脚本中加载进来,通常取名Utilities.php,也可是Common.php,这里的Common.php也是这个意思,如它的解释是“加载全局函数”,即这里的函数都是后边直接拿来用的。在这个脚本中有两个重要的方法(目前来说)一个是get_config,单独拿出来如下
1 php 2 /** 3 * Loads the main config.php file 4 * 5 * This function lets us grab the config file even if the Config class 6 * hasn't been instantiated yet 7 * 8 * @access private 9 * @return array 10 */ 11 if ( ! function_exists('get_config')) 12 { 13 function &get_config($replace = array()) 14 { 15 static $_config; 16 17 if (isset($_config)) 18 { 19 return $_config[0]; 20 } 21 22 // Is the config file in the environment folder? 23 if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) 24 { 25 $file_path = APPPATH.'config/config.php'; 26 } 27 28 // Fetch the config file 29 if ( ! file_exists($file_path)) 30 { 31 exit('The configuration file does not exist.'); 32 } 33 34 require($file_path); 35 36 // Does the $config array exist in the file? 37 if ( ! isset($config) OR ! is_array($config)) 38 { 39 exit('Your config file does not appear to be formatted correctly.'); 40 } 41 42 // Are any values being dynamically replaced? 43 if (count($replace) > 0) 44 { 45 foreach ($replace as $key => $val) 46 { 47 if (isset($config[$key])) 48 { 49 $config[$key] = $val; 50 } 51 } 52 } 53 54 $_config[0] =& $config; 55 return $_config[0]; 56 } 57 } View Code注释说它加载主要的config.php文件,它使得我们能抓取到配置文件,即便配置类还未被实例化。在CI中,有专门的核心配置类CI_Config来加载配置信息,而这里的get_config方法也能获得主要配置信息,注意是主要配置信息,在application/config目录下有很多其他的配置信息文件(前面在自定义配置变量时也说过CI将配置信息分为了很多文件),其中有一个config.php文件就是get_config能获取到的,这个文件存放的就是基本信息,如果你还想获取其他的配置信息,貌似就要用配置类了。所以如果想添加节本配置信息就在这个里边。
If it is the first time to call the get_config method, first declare the static variable $_config. If it has been defined, directly return its subarray with index 0. Then check whether the APPPATH/config/ENVIRONMENT/config.php file exists (the known ENVIRONMENT constant value was printed previously, and the unchanged value is development. There is no such directory in the original framework, so application/config/config.php is loaded here (only This one is loaded, but other configuration files are not), you can open it to see a $config array defined in config.php, some basic definitions such as basic links, link suffixes, encoding, language, cache, logs, hooks, etc. If. Passing in an associative array, it will add the key-value (temporary) to $_config. In short, the get_config method mainly gets the array variables defined in config.php.
The config_item method related to get_config is to get an item in this array variable.Another important method is load_class:
1 php 2 /** 3 * Class registry 4 * 5 * This function acts as a singleton. If the requested class does not 6 * exist it is instantiated and set to a static variable. If it has 7 * previously been instantiated the variable is returned. 8 * 9 * @access public 10 * @param string the class name being requested 11 * @param string the directory where the class should be found 12 * @param string the class name prefix 13 * @return object 14 */ 15 if ( ! function_exists('load_class')) 16 { 17 function &load_class($class, $directory = 'libraries', $prefix = 'CI_') 18 { 19 static $_classes = array(); 20 21 // Does the class exist? If so, we're done... 22 if (isset($_classes[$class])) 23 { 24 return $_classes[$class]; 25 } 26 27 $name = FALSE; 28 29 // Look for the class first in the local application/libraries folder 30 // then in the native system/libraries folder 31 foreach (array(APPPATH, BASEPATH) as $path) 32 { 33 if (file_exists($path.$directory.'/'.$class.'.php')) 34 { 35 $name = $prefix.$class; 36 37 if (class_exists($name) === FALSE) 38 { 39 require($path.$directory.'/'.$class.'.php'); 40 } 41 42 break; 43 } 44 } 45 46 // Is the request a class extension? If so we load it too 47 if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php')) 48 { 49 $name = config_item('subclass_prefix').$class; 50 51 if (class_exists($name) === FALSE) 52 { 53 require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'); 54 } 55 } 56 57 // Did we find the class? 58 if ($name === FALSE) 59 { 60 // Note: We use exit() rather then show_error() in order to avoid a 61 // self-referencing loop with the Excptions class 62 exit('Unable to locate the specified class: '.$class.'.php'); 63 }64 65 // Keep track of what we just loaded 66 is_loaded($class); 67 68 $_classes[$class] = new $name(); 69 return $_classes[$class]; 70 } 71 } View Code
Let’s look at its comments first: This method acts as a singleton. If the requested class does not appear before, the class will be instantiated as a static variable. If it has been instantiated before, it will be returned directly. Its three parameters are the requested class name, directory, and class name prefix. As you can see, the default directory is libraries, which is found in both application and system. It is where our custom class libraries or class libraries that come with CI are stored, including custom tools and tools provided by CI, such as calendar classes. , encryption class, Ftp class, log class, Session class, Email sending and receiving class, JavaScript class, ZIP compression class, etc. Perhaps you have noticed that a reference is returned instead of a value, just like it loads the class as a static variable. These details ultimately improve the access speed of the entire system.
The general process: first define a static array, and return it directly if the class already exists in the array. Scan the $directory (default value is libraries) directory under the APPPATH and BASEPATH (these two constant values are known before) folders to see if the $class.php file exists. If it exists, add the standard class prefix of CI_ (the third one). The default value of each parameter), when checking whether the class exists, require the file if it exists (it can be seen from here that class_exists() does not need to load the class file first when determining whether the class exists), and once the file appears, load it, And break jumps out. Pay attention to the scanning order, first APPPATH and then BASEPATH. If only the first parameter class name is passed, we will first search in the libraries of the application directory we developed ourselves, and then go to the libraries of the system directory.
Since we can extend the core classes of CI (inherit them), after scanning the core class (names prefixed with CI_) directories of APPPATH and BASEPATH, we must also scan whether there are customizations under the libraries of APPPATH extension classes (prefixed by MY_ by default), load them if any, and then instantiate a corresponding object (if there is an extension class, it is an extension class), store it in the $_classes static array and return the object.
Return to the CodeIgniter.php script after you have a general understanding of Common.php.
Lines 54-66: Load the APPPATH.'config/constants.php' script. Constants.php, as the name suggests, contains framework constants, which centrally defines some constants, so we can put them here when adding constants. to define.
Lines 68-78: First, a custom error handling method _exception_handler is defined. Determine the PHP version. If it is not 5.3, turn off the magic_quotes reference. This configuration has been deprecated in version 5.3 to improve security.
Lines 80-99: Here is the temporary addition of the $assign_to_config custom configuration information array mentioned earlier to the $_config array, implemented through the get_config method. As mentioned earlier, $assign_to_config is not defined by default. The if statement here It won't run either.
Lines 101-109: Set the maximum execution time of the custom script to 300 seconds (slightly longer, longer if running logs)
Lines 111-118: Load the core class Benchmark and set two mark points. The Benchmark benchmark test class is to test the memory size, execution time and other information occupied between a certain start mark and the end mark. For testing, of course it must be used in conjunction with something called an analyzer in CI.
Lines 120-132: Load the core class Hooks, hook, and set a hook that the system starts to execute (actually not executed because the configuration information about it in application/config/config.php is set to false by default, that is, the hook is not enabled) ). It is equivalent to a trigger that starts executing certain code before something is to be executed, such as before the controller is loaded, after loading, etc., and runs the specified code once the controller is loaded. Here, it attempts to call a pre_system (before system execution) extension, which is not executed by default.
Lines 134-145: Load the core class Config, the configuration class, which is used to load other required configuration information, and it loads the configuration information in the $assign_to_config array again if the array is defined.
Lines 147-159: Load core class Utf8, encoding class.
Lines 161-166: Load core class URI, routing.
Lines 168-180: Load the core class Router, the path processing class, and the _set_routing method to set the access path. If the path configuration array $routing (mentioned as commented out by default) is defined, the default routing configuration will be overridden. If you enter a script path that does not exist, it will stop at this step and start reporting 404. Of course, it must be handled by the method in the Router.
In the Router class, URI exists as a member of it. The actual processing method is in the URI class. Anyone who is familiar with it knows that the access method of CI is in the form of segment by default, which is said to be more conducive to search engines. A simple access method is localhost/ci/index.php/Controller/Function/Arguments. They parse the access form into the required controller, the method to be called, and the provided parameter list. Of course, traditional methods can also be enabled. Query string form. The specific method is slightly complicated.
Line 187: Load the core class Output.
Lines 189-200: Use the Hooks class and the Output class to detect whether there is cache. If there is, the cache page will be output directly and the script will jump out. This is also the reason why in the application flow chart part of the CI introduction, after the path is processed, if there is a cache, it will be output directly.
Line 207: Load the core class Security.
Line 214: Load the core class Input.
Line 221: Load core class Lang, language processing.
Lines 229-235: Load the core class Controller, which is the base class of all controllers, and the get_instance global method can also get its instance. The cool thing about Controller is that it will load all the previous ones loaded through load_calss Tool libraries in the libraries (default) directories (APPPATH and BASEPATH) are all instantiated as objects and as its property members. Therefore, the instance obtained by the get_instance method here is also called a super object by CI, because through this object, all previously loaded object instances can be obtained.
Lines 238-242: Load a custom extension class file for the core class CI_Controller in the previous step. The default is MY_Controller, of course, if you have extended it.
Lines 243-251: Extract the directory and class name of the currently accessed controller through the instance of the core class Router. If it does not exist, an error will be reported. If it exists, it will be loaded. The default welcome controller file is loaded here. Of course, if you define the controller class file yourself and access it, it will also be included here (extract the subdirectory $RTR->fetch_directory() through the Router class, if it exists, extract the class name $RTR->fetch_class() (Look for it), the if statement block on line 246 is to check whether this class file exists.
Line 252: Set a benchmark end mark to mark the end of loading basic core classes (these tests will not be executed by default).
Lines 256-292: Security check. First, obtain the class name and the method name to be executed through the Router class, and check three items in the if condition. 1. Lines 243-251 above find the script corresponding to the controller and load it, but what if this is just an empty script with a matching name? It won't work if nothing is written inside, so you need to check whether the definition of the class exists (class_exists). 2. Method names starting with underscore _ cannot be executed and an error will be reported directly. Of course, this is CI's own rule, which means that no matter you The methods starting with _ defined by the class will not work even if they are public access attributes (except for one _remap). 3. When the method in the class has the same name as the method in the core class of the root controller, it will not work. Just have an impression when defining the method name. Entering the if is likely to result in a 404.
Line 298: The Hooks class attempts to call a pre_controller (before the controller is executed) extension, which is not available by default.
Lines 301-309: The benchmark class sets a starting point mark to test the execution time of the controller (test information is not displayed by default), and instantiates the previously loaded controller class. The default is Welcome.
Line 315: Hooks attempts to execute the extension of post_controller_constructor (after the called controller class is constructed), which is not available by default.
Lines 317-364: Start calling the specified method of the specified controller class (of course this is the default method index of the default controller Welcome). Take a look at this process. First, make an if judgment. If there is a method _remap in your controller class, just call it. So the methods starting with an underscore are except _remap. This is also the rule for methods of a CI class. With this remapping method, just adjust it. There is no _remap method in the default Welcome controller. Enter else. There is an if in else. Judge again whether the method we call is in this controller class. If not, it is destined to be 404. It is just 404.