CI框架源码解析一之入口文件index.php

    转摘原文:原文


Index.php作为CI框架的入口文件,源码分析,自然而然由此开始。在源码分析的过程中,我们并不会逐行进行解释,而只解释核心的功能和实现,如果英文水平很好的话,读过index.php文件的英文注释之后也就基本明白了inde.php都做了些什么。本来想第一篇写解析CI框架的目录结构的,像这一般网上一搜都是一大堆,也就放弃了这个想法。博主是基于CodeIgniter-v3.1.0最新版本进行解读分析。ok,书归正传,在博主看来CI框架的index.php文件一共完成了四项工作:

① 设置框架应用的环境状态

② 配置系统、应用、视图等程序目录以及得到其路径

③ 系统、应用、视图等目录的正确性验证

④ 载入 core/CodeIgniter.php框架核心文件,启动框架

1、设置框架应用的环境状态

[php]  view plain  copy
  1. define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');  

        这里的development可以是任何你喜欢的环境名称(比如working,再如debug),相对应的,你要在下面的switch case代码块中,对设定的环境做相关的错误等级控制。(CI框架设置了三种应用场景状态,分别是:development(开发),testing(测试),production(产品)。development(开发)状态,也就是默认的状态下会产生错误报告,testing(测试),production(产品)状态下则不会产生错误报告)否则,CI框架会认为你没有配置好相应的环境,从而退出进程并给出对应的错误信息:

[php]  view plain  copy
  1. default:  
  2.     //header() 被用来发送自定义的 HTTP 报文。关于HTTP报文的更多信息请参考php手册  
  3.     header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);  
  4.     echo 'The application environment is not set correctly.';  
  5.     exit(1);   

        之所以一定要配置配置ENVIRONMENT?这是因为,CI框架中很多组件都依赖于ENVIRONMENT的配置,例如,查看system/config/Common.php, 这其中有一段引入配置文件的代码,是这样实现的:

[php]  view plain  copy
  1. if (file_exists(APPPATH . 'config/' . ENVIRONMENT . '/mimes.php')) {  
  2.     $_mimes = include(APPPATH . 'config/' . ENVIRONMENT . '/mimes.php');  
  3. elseif (file_exists(APPPATH . 'config/mimes.php')) {  
  4.     $_mimes = include(APPPATH . 'config/mimes.php');  
  5. else {  
  6.     $_mimes = array();  
  7. }  

        在CI框架中,很多配置文件都是通过这种方式引入的,因此ENVRIONMENT对于CI框架的正确运行时必须的,所以需要在开始的时候配置好ENVIRONMENT。设置ENVIRONMENT的一个好处是:可以很方便的切换系统的配置而不必修改系统代码。例如,在系统进入测试阶段时,database配置为测试的数据库,而在系统测试完毕时,database切换到线上的数据库。这好比是用一个开关控制了系统的环境切换,自然是非常方便的。

2、配置系统、应用、视图等程序目录以及得到其路径

        CI框架允许你将系统核心源码和应用程序代码进行分开放置,但是你必须设定好系统的system文件夹和application文件夹(同样,文件夹名字可以是任何合法的文件夹名称,而不一定使用’system’和’application’)的名称、路径等信息:

[php]  view plain  copy
  1. //定义系统目录名称  
  2. $system_path = 'system';  
  3.   
  4. //定义你的应用目录名称  
  5. $application_folder = 'application';  
  6.   
  7. //视图文件存放目录  
  8. //如果要将视图目录移到应用程序目录,则设置在此处的路径。如果空白,它将默认为您的应用程序目录中的标准位置。  
  9. $view_folder = '';  

        下面有这样一段代码,然后很多人就不明白为什么要放这样几句代码了,在这里特别说明一下:

[php]  view plain  copy
  1. if (defined('STDIN')) {  
  2.     //chdir函数用来改变目录  
  3.     chdir(dirname(__FILE__));  
  4. }  

        这段代码主要是用来干嘛的呢?首先,STDIN、STDOUT、STDERR是PHP以 CLI(Command Line Interface)模式运行而定义的三个常量,这三个常量类似于Shell的stdin,stdout,stdout,分别是PHP CLI模式下的标准输入、标准输出和标准错误流。也就是说,这三行代码是为了保证命令行模式下,CI框架可以正常运行。

3、系统、应用、视图等目录的正确性验证

1) 系统(system)文件目录的正确性验证

[php]  view plain  copy
  1. //得到规范化的绝对路径名  
  2. //此段代码用于判断生成system系统文件目录  
  3. if (($_temp = realpath($system_path)) !== FALSE) {  
  4.     //$system_path就是当前你的CI框架核心文件所存放的绝对路径名  
  5.     $system_path = $_temp . DIRECTORY_SEPARATOR;  
  6. else {  
  7.     $system_path = strtr(rtrim($system_path'/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;  
  8. }  
  9.   
  10. //如果$system_path所指向的文件目录不存在,则die  
  11. if (!is_dir($system_path)) {  
  12.     header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);  
  13.     echo 'Your system folder path does not appear to be set correctly. Please open the following file and correct this: ' . pathinfo(__FILE__, PATHINFO_BASENAME);  
  14.     exit(3); // EXIT_CONFIG  
  15. }  

2) 应用(application)文件目录的正确性验证

[php]  view plain  copy
  1. //此段代码用于判断生成application应用文件目录  
  2. if (is_dir($application_folder)) {  
  3.     if (($_temp = realpath($application_folder)) !== FALSE) {  
  4.         $application_folder = $_temp;  
  5.     } else {  
  6.         $application_folder = strtr(rtrim($application_folder'/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR);  
  7.     }  
  8. elseif (is_dir(BASEPATH . $application_folder . DIRECTORY_SEPARATOR)) {  
  9.     $application_folder = BASEPATH . strtr(trim($application_folder'/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR);  
  10. else {  
  11.     header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);  
  12.     echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: ' . SELF;  
  13.     exit(3);  
  14. }  

3) 视图(view)文件目录的正确性验证

[php]  view plain  copy
  1. //此段代码用于判断生成view视图文件目录  
  2. if (!isset($view_folder[0]) && is_dir(APPPATH . 'views' . DIRECTORY_SEPARATOR)) {  
  3.     $view_folder = APPPATH . 'views';  
  4. elseif (is_dir($view_folder)) {  
  5.     if (($_temp = realpath($view_folder)) !== FALSE) {  
  6.         $view_folder = $_temp;  
  7.     } else {  
  8.         $view_folder = strtr(rtrim($view_folder'/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR);  
  9.     }  
  10. elseif (is_dir(APPPATH . $view_folder . DIRECTORY_SEPARATOR)) {  
  11.     $view_folder = APPPATH . strtr(trim($view_folder'/\\'), '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR);  
  12. else {  
  13.     header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);  
  14.     echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: ' . SELF;  
  15.     exit(3);  
  16. }  

        几个定义的常量(PATH结尾的常量表示目录路径,DIR结尾的变量表示目录名):

[php]  view plain  copy
  1. //SELF(这里指index.php文件)  
  2. define('SELF'pathinfo(__FILE__, PATHINFO_BASENAME));  
  3. //BASEPATH(system文件夹的路径)  
  4. define('BASEPATH'$system_path);  
  5. //FCPATH(前端控制器的路径)  
  6. define('FCPATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);  
  7. //SYSDIR(系统system目录名)  
  8. define('SYSDIR'basename(BASEPATH));  
  9. //APPPATH(应用程序路径)  
  10. define('APPPATH'$application_folder . DIRECTORY_SEPARATOR);  
  11. //VIEWPATH(视图目录路径)  
  12. define('VIEWPATH'$view_folder . DIRECTORY_SEPARATOR);  

       注:查看所有常量的方法:

[php]  view plain  copy
  1. var_dump(get_defined_constants());  

4、载入 core/CodeIgniter.php框架核心文件,启动框架

       入口文件的最后一行,引入CodeIgniter.php框架核心文件(也是下一步框架执行的关键)。CodeIgniter.php被称为bootstrap file,也就是它是一个引导文件,是CI框架执行流程的核心文件。

[php]  view plain  copy
  1. //最后就是加载CI框架的核心引导文件了  
  2. require_once BASEPATH . 'core/CodeIgniter.php';  

        总结一下,index.php并没有做太多复杂的工作,而是类似军队中押运粮草的,兵马未动粮草先行,为CI框架的运行提供了一系列配置参数和正确性验证,而这些配置和验证,是CI框架能够正常运行的关键。

        最后,贴一下整个index.php文件的源码(注释版):

[php]  view plain  copy
  1. <?php  
  2.   
  3. /** 
  4.  * ======================================= 
  5.  * Created by Pocket Knife Technology. 
  6.  * User: ZhiHua_W 
  7.  * Date: 2016/10/14 0020 
  8.  * Time: 下午 2:14 
  9.  * Project: CodeIgniter框架—源码分析 
  10.  * Power: Analysis for Index.php 
  11.  * ======================================= 
  12.  */  
  13.   
  14. /** 
  15.  * 框架的第一步就是定义框架代码当前的使用场景状态 
  16.  * 一共有development(开发),testing(测试),production(产品)三个场景状态 
  17.  * 不同的场景状态将会产生不同级别的错误报告 
  18.  */  
  19. define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');  
  20.   
  21. /** 
  22.  * 这里就会对场景状态进行判断 
  23.  * development(开发)状态,也就是默认的状态下会产生错误报告 
  24.  * testing(测试),production(产品)状态下则不会产生错误报告 
  25.  */  
  26. switch (ENVIRONMENT) {  
  27.     case 'development':  
  28.         //error_reporting()函数是php的内置函数,用来设置php的报错级别并返回当前级别  
  29.         //函数语法:  
  30.         //error_reporting(report_level) report_level参数是错误等级,一共有已下几种:  
  31.         //值 常量 描述  
  32.         //1 E_ERROR 致命的运行错误。错误无法恢复,暂停执行脚本  
  33.         //2 E_WARNING 运行时警告(非致命性错误)。非致命的运行错误,脚本执行不会停止  
  34.         //4 E_PARSE 编译时解析错误。解析错误只由分析器产生  
  35.         //8 E_NOTICE 运行时提醒(这些经常是你代码中的bug引起的,也可能是有意的行为造成的。)  
  36.         //16 E_CORE_ERROR PHP启动时初始化过程中的致命错误  
  37.         //32 E_CORE_WARNING PHP启动时初始化过程中的警告(非致命性错)。  
  38.         //64 E_COMPILE_ERROR 编译时致命性错。这就像由Zend脚本引擎生成了一个E_ERROR  
  39.         ///128 E_COMPILE_WARNING 编译时警告(非致命性错)。这就像由Zend脚本引擎生成了一个E_WARNING警告  
  40.         //256 E_USER_ERROR 用户自定义的错误消息。这就像由使用PHP函数trigger_error(程序员设置E_ERROR)  
  41.         //512 E_USER_WARNING 用户自定义的警告消息。这就像由使用PHP函数trigger_error(程序员设定的一个E_WARNING警告)  
  42.         //1024 E_USER_NOTICE 用户自定义的提醒消息。这就像一个由使用PHP函数trigger_error(程序员一个E_NOTICE集)  
  43.         //2048 E_STRICT 编码标准化警告。允许PHP建议如何修改代码以确保最佳的互操作性向前兼容性  
  44.         //4096 E_RECOVERABLE_ERROR 开捕致命错误。这就像一个E_ERROR,但可以通过用户定义的处理捕获(又见set_error_handler())  
  45.         //8191 E_ALL 所有的错误和警告(不包括 E_STRICT) (E_STRICT will be part of E_ALL as of PHP 6.0)  
  46.         //更为具体的用法大家可以查询php手册  
  47.         error_reporting(-1);  
  48.   
  49.         //ini_set用来设置php.ini的值,在函数执行的时候生效,脚本结束后,设置失效。  
  50.         //无需打开php.ini文件,就能修改配置,对于虚拟空间来说,很方便。  
  51.         //不是所有的参数都可以配置,可以查看手册中的列表。  
  52.         //可以使用ini_get来获取所设置的值,例如:echo ini_get('display_errors');  
  53.         ini_set('display_errors', 1);  
  54.   
  55.         break;  
  56.   
  57.     case 'testing':  
  58.     case 'production':  
  59.         ini_set('display_errors', 0);  
  60.   
  61.         //version_compare() 用于对比两个「PHP 规范化」的版本数字字符串。 这对于编写仅能兼容某些版本 PHP 的程序很有帮助。  
  62.         if (version_compare(PHP_VERSION, '5.3''>=')) {  
  63.             error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);  
  64.         } else {  
  65.             error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE);  
  66.         }  
  67.         break;  
  68.   
  69.     default:  
  70.         //header() 被用来发送自定义的 HTTP 报文。关于HTTP报文的更多信息请参考php手册  
  71.         header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);  
  72.         echo 'The application environment is not set correctly.';  
  73.         exit(1); // EXIT_ERROR  
  74. }  
  75.   
  76. /** 
  77.  * 定义系统目录名称 
  78.  * 此变量必须包含您的“系统”目录的名称。如果它不在与此文件相同的目录中,则设置路径。 
  79.  * 里面存放的是CI框架的各种核心文件。 
  80.  */  
  81. $system_path = 'system';  
  82.   
  83. /** 
  84.  * 定义你的应用目录名称 
  85.  * 如果你希望此前控制器使用不同的“应用程序”目录,而不是默认的“应用程序”目录,你可以在这里设置它的名称。 
  86.  */  
  87. $application_folder = 'application';  
  88.   
  89. /** 
  90.  * 视图文件存放目录 
  91.  * 如果要将视图目录移到应用程序目录,则设置在此处的路径。如果空白,它将默认为您的应用程序目录中的标准位置。 
  92.  */  
  93. $view_folder = '';  
  94.   
  95.   
  96. // --------------------------------------------------------------------  
  97. // END OF USER CONFIGURABLE SETTINGS.  DO NOT EDIT BELOW THIS LINE  
  98. //用户可配置设置的结束。不要在这条线下编辑  
  99. //这里只是CI框架进行一下提示,如果你想改动的话,还是可以的  
  100. // --------------------------------------------------------------------  
  101.   
  102.   
  103. //设置正确的目录  
  104. /** 
  105.  * STDIN、STDOUT、STDERR是PHP以 CLI(Command Line Interface)模式运行而定义的三个常量, 
  106.  * 这三个常量类似于Shell的stdin,stdout,stdout,分别是PHP CLI模式下的标准输入、标准输出和标准错误流。 
  107.  * 也就是说,这三行代码是为了保证命令行模式下,CI框架可以正常运行。 
  108.  */  
  109. if (defined('STDIN')) {  
  110.     //chdir函数用来改变目录  
  111.     chdir(dirname(__FILE__));  
  112. }  
  113. //得到规范化的绝对路径名  
  114. //此段代码用于判断生成system系统文件目录  
  115. if (($_temp = realpath($system_path)) !== FALSE) {  
  116.     //$system_path就是当前你的CI框架核心文件所存放的绝对路径名  
  117.     $system_path = $_temp . DIRECTORY_SEPARATOR;  
  118. else {  
  119.     $system_path = strtr(  
  120.             rtrim($system_path'/\\'),  
  121.             '/\\',  
  122.             DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR  
  123.         ) . DIRECTORY_SEPARATOR;  
  124. }  
  125.   
  126. //如果$system_path所指向的文件目录不存在,则die  
  127. if (!is_dir($system_path)) {  
  128.     header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);  
  129.     echo 'Your system folder path does not appear to be set correctly. Please open the following file and correct this: ' . pathinfo(__FILE__, PATHINFO_BASENAME);  
  130.     exit(3); // EXIT_CONFIG  
  131. }  
  132.   
  133. /** 
  134.  * 下面主要是设置各种主要的常量 
  135.  */  
  136. //当前文件名称,也就是“index.php”  
  137. //pathinfo()函数返回文件路径的信息  
  138. define('SELF'pathinfo(__FILE__, PATHINFO_BASENAME));  
  139.   
  140. //system文件的绝对路径  
  141. define('BASEPATH'$system_path);  
  142.   
  143. //项目文件目录的绝对路径  
  144. //dirname()函数返回路径中的目录部分  
  145. define('FCPATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);  
  146.   
  147. // system文件夹名称“system”  
  148. //basename()函数返回路径中的文件名部分  
  149. define('SYSDIR'basename(BASEPATH));  
  150.   
  151. //此段代码用于判断生成application应用文件目录  
  152. if (is_dir($application_folder)) {  
  153.     if (($_temp = realpath($application_folder)) !== FALSE) {  
  154.         $application_folder = $_temp;  
  155.     } else {  
  156.         $application_folder = strtr(  
  157.             rtrim($application_folder'/\\'),  
  158.             '/\\',  
  159.             DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR  
  160.         );  
  161.     }  
  162. elseif (is_dir(BASEPATH . $application_folder . DIRECTORY_SEPARATOR)) {  
  163.     $application_folder = BASEPATH . strtr(  
  164.             trim($application_folder'/\\'),  
  165.             '/\\',  
  166.             DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR  
  167.         );  
  168. else {  
  169.     header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);  
  170.     echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: ' . SELF;  
  171.     exit(3); // EXIT_CONFIG  
  172. }  
  173. //application应用目录的绝对路径  
  174. define('APPPATH'$application_folder . DIRECTORY_SEPARATOR);  
  175.   
  176. //此段代码用于判断生成view视图文件目录  
  177. if (!isset($view_folder[0]) && is_dir(APPPATH . 'views' . DIRECTORY_SEPARATOR)) {  
  178.     $view_folder = APPPATH . 'views';  
  179. elseif (is_dir($view_folder)) {  
  180.     if (($_temp = realpath($view_folder)) !== FALSE) {  
  181.         $view_folder = $_temp;  
  182.     } else {  
  183.         $view_folder = strtr(  
  184.             rtrim($view_folder'/\\'),  
  185.             '/\\',  
  186.             DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR  
  187.         );  
  188.     }  
  189. elseif (is_dir(APPPATH . $view_folder . DIRECTORY_SEPARATOR)) {  
  190.     $view_folder = APPPATH . strtr(  
  191.             trim($view_folder'/\\'),  
  192.             '/\\',  
  193.             DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR  
  194.         );  
  195. else {  
  196.     header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);  
  197.     echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: ' . SELF;  
  198.     exit(3); // EXIT_CONFIG  
  199. }  
  200. //view视图目录的绝对路径  
  201. define('VIEWPATH'$view_folder . DIRECTORY_SEPARATOR);  
  202.   
  203. //最后就是加载CI框架的核心引导文件了  
  204. require_once BASEPATH . 'core/CodeIgniter.php';  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
http.c是goahead web服务器的核心文件之一,主要负责处理HTTP请求和响应。以下是http.c文件源码解析: 1. 首先,http.c文件包含了一些必要的头文件,例如<sys/stat.h>和<fcntl.h>等。这些头文件提供了一些系统级别的函数和结构体。 2. 接着,http.c中定义了一些常量、宏和全局变量。例如,HTTP请求方法的枚举类型、HTTP响应状态码的宏定义、HTTP请求头部的结构体等。 3. 然后,http.c中定义了一些函数,这些函数负责处理HTTP请求和响应。例如,processHttpRequest()函数用于处理HTTP请求,sendHttpResponse()函数用于发送HTTP响应,parseFirstLine()函数用于解析HTTP请求的第一行等。 4. 在processHttpRequest()函数中,首先解析HTTP请求的第一行,然后解析HTTP请求头部,最后根据HTTP请求方法调用不同的处理函数。例如,如果是GET方法,就调用processGetRequest()函数处理请求。 5. 在processGetRequest()函数中,首先解析HTTP请求的路径,然后判断该路径是否合法,最后打开文件并发送HTTP响应。如果文件无法打开或者发送失败,就发送相应的错误响应。 6. 在sendHttpResponse()函数中,首先根据HTTP响应状态码设置响应头部,然后将响应头部和主体发送给客户端。 7. 最后,在main()函数中,启动goahead web服务器,并监听指定的端口号,等待客户端连接。 以上就是http.c文件源码解析

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值