CI框架源码解读(1)-入口文件index.php
参考:http://www.cnblogs.com/ohmygirl/p/CIRead-2.html
入口文件是进入一个框架的开始,下面分析下CI入口文件。
一.所属目录,根目录
CI将入口文件放在根目录,而不是像yii或laravel或新版本TP将入口文件放到根目录下一个文件中,原因和禁止直接访问文件的处理之后再做分析。
二.内部结构
1.开发环境设置
define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development'); switch (ENVIRONMENT) { case 'development': error_reporting(-1); ini_set('display_errors', 1); break; case 'testing': case 'production': ini_set('display_errors', 0); if (version_compare(PHP_VERSION, '5.3', '>=')) { error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED); } else { error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE); } break; default: header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); echo 'The application environment is not set correctly.'; exit(1); // EXIT_ERROR }
之所以一开始就设置环境变量是因为,CI框架中很多组件都依赖于ENVIRONMENT的配置,如system
localhost:system root# grep ENVIRONMENT ./* -R ./core/CodeIgniter.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php')) ./core/CodeIgniter.php: require_once(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); ./core/Common.php: if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) ./core/Common.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) ./core/Common.php: $_mimes = include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'); ./core/Config.php: foreach (array($file, ENVIRONMENT.DIRECTORY_SEPARATOR.$file) as $location) ./core/Hooks.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/hooks.php')) ./core/Hooks.php: include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'); ./core/Loader.php: if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')) ./core/Loader.php: include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'); ./core/Loader.php: elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')) ./core/Loader.php: include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'); ./core/Loader.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')) ./core/Loader.php: include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'); ./core/Router.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php')) ./core/Router.php: include(APPPATH.'config/'.ENVIRONMENT.'/routes.php'); ./database/DB.php: if ( ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php') ./database/DB.php: if (file_exists($file_path = $path.'config/'.ENVIRONMENT.'/database.php')) ./helpers/html_helper.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php')) ./helpers/html_helper.php: include(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php'); ./helpers/smiley_helper.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys.php')) ./helpers/smiley_helper.php: include(APPPATH.'config/'.ENVIRONMENT.'/smileys.php'); ./helpers/text_helper.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php')) ./helpers/text_helper.php: include(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php'); ./libraries/User_agent.php: if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php')) ./libraries/User_agent.php: include(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php');
这样就可以在不改变代码的情况下,方便根据环境做一些特殊的不同的配置,如数据库配置文件的加载:
if (file_exists($file_path = $path.'config/'.ENVIRONMENT.'/database.php')) { include($file_path); } elseif (file_exists($file_path = $path.'config/database.php')) { include($file_path); }
2. 定义常量信息
$system_path = 'system'; $application_folder = 'application'; $view_folder = ''; // The name of THIS file define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME)); // Path to the system directory define('BASEPATH', $system_path); // Path to the front controller (this file) directory define('FCPATH', dirname(__FILE__).DIRECTORY_SEPARATOR); // Name of the "system" directory define('SYSDIR', basename(BASEPATH)); define('APPPATH', $application_folder.DIRECTORY_SEPARATOR); define('VIEWPATH', $view_folder.DIRECTORY_SEPARATOR);
其中省略了对$system_path、$application_folder、$view_folder的验证和正对不同系统的处理如对$view_folder的处理:
// The path to the "views" directory if ( ! isset($view_folder[0]) && is_dir(APPPATH.'views'.DIRECTORY_SEPARATOR)) { $view_folder = APPPATH.'views'; } elseif (is_dir($view_folder)) { if (($_temp = realpath($view_folder)) !== FALSE) { $view_folder = $_temp; } else { $view_folder = strtr( rtrim($view_folder, '/\\'), '/\\', DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR ); } } elseif (is_dir(APPPATH.$view_folder.DIRECTORY_SEPARATOR)) { $view_folder = APPPATH.strtr( trim($view_folder, '/\\'), '/\\', DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR ); } else { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF; exit(3); // EXIT_CONFIG }
还有这样一段代码,首先,STDIN、STDOUT、STDERR是PHP以 CLI(Command Line Interface)模式运行而定义的三个常量,这三个常量类似于Shell的stdin,stdout,stderr,分别是PHP CLI模式下的标准输入、标准输出和标准错误流。也就是说,这三行代码是为了保证命令行模式下,CI框架可以正常运行。关于PHP CLI的更多细节可以参考:http://www.php-cli.com/
if (defined('STDIN')) { chdir(dirname(__FILE__)); }
3.引入CI的 boostrap file --CodeIgniter.php,这个文件是之后的处理流程关键
require_once BASEPATH.'core/CodeIgniter.php';