PHP SAPI(CGI)个人整理

cgi程序的入口函数在/sapi/cgi/cgi_main.c中,同样透过源码来看看CGI程序是如何启动的.

首先CGI跟CLI程序的运行做一个大概的对比一下,个人总结,有错误请指正:
1、CLI启动是在终端执行,其参数通过终端指定
2、CGI启动是通过web服务器执行,当WEB服务器接受到HTTP请求以后,调用(应该类似exec)入口方法,参数的传递通过环境变量指定,具体哪些参数可以查看CGI协议的规定。



那么PHP CGI模式的运行是如何运行的呢? 因为FASTCGI和CGI是在同一文件里面做了判断,这里直接去掉FASTCGI的代码,省略部分代码作出说明:

1、定义了一些常量
  int  free_query_string = 0;
     int  exit_status = SUCCESS;
     int  cgi = 0, c, i, len;
     zend_file_handle file_handle;
     char  *s;
 
     /* temporary locals */
     int  behavior = PHP_MODE_STANDARD;
     int  no_headers = 0;
     int  orig_optind = php_optind;
     char  *orig_optarg = php_optarg;
     char  *script_file = NULL;
     int  ini_entries_len = 0;
     /* end of temporary locals */
     int max_requests = 500;
    int requests = 0;
    int fastcgi;
    char *bindpath = NULL;
    int fcgi_fd = 0;
    fcgi_request *request = NULL;
    int repeats = 1;
    int benchmark = 0;
signal(SIGPIPE, SIG_IGN); /* 信号量设置*/
sapi_startup(&cgi_sapi_module); //设置一些全局常量,比如SG,设置php.ini的设置选项
//.........读取参数,设置一些全局变量

//请求初始化操作。请求初始化操作,除了图中显示的调用每个模块的请求初始化函数外,
// 激活Zend引擎,激活SAPI,环境初始化,包括了$_GET,$_POST等
if (php_request_startup(TSRMLS_C) == FAILURE) {
   if (fastcgi) {
      fcgi_finish_request(request, 1);
   }
   SG(server_context) = NULL;
   php_module_shutdown(TSRMLS_C);
   return FAILURE;
}



switch  (behavior) {
                 case  PHP_MODE_STANDARD:
                     php_execute_script(&file_handle TSRMLS_CC);
                     break ;
                 case  PHP_MODE_LINT:
                     PG(during_request_startup) = 0;
                     exit_status = php_lint_script(&file_handle TSRMLS_CC);
                     if  (exit_status == SUCCESS) {
                         zend_printf( "No syntax errors detected in %s\n" , file_handle.filename);
                     else  {
                         zend_printf( "Errors parsing %s\n" , file_handle.filename);
                     }
                     break ;
                 case  PHP_MODE_STRIP:
                     if  (open_file_for_scanning(&file_handle TSRMLS_CC) == SUCCESS) {
                         zend_strip(TSRMLS_C);
                         zend_file_handle_dtor(&file_handle TSRMLS_CC);
                         php_output_teardown();
                     }
                     return  SUCCESS;
                     break ;
                 case  PHP_MODE_HIGHLIGHT:
                     {
                         zend_syntax_highlighter_ini syntax_highlighter_ini;
 
                         if  (open_file_for_scanning(&file_handle TSRMLS_CC) == SUCCESS) {
                             php_get_highlight_struct(&syntax_highlighter_ini);
                             zend_highlight(&syntax_highlighter_ini TSRMLS_CC);
                             if  (fastcgi) {
                                 goto  fastcgi_request_done;
                             }
                             zend_file_handle_dtor(&file_handle TSRMLS_CC);
                             php_output_teardown();
                         }
                         return  SUCCESS;
                     }
                     break ;
behavior是由之前的代码决定的,我们看到标准的就可以了
php_execute_script函数包含了运行PHP脚本的全部过程。

具体来看下php_request_start函数的执行,就跟CLI模式下的do_cli一样。
int  php_request_startup(TSRMLS_D)
{
     int  retval = SUCCESS;
 
#if PHP_SIGCHILD
     signal (SIGCHLD, sigchld_handler);
#endif
 
     if  (php_start_sapi() == FAILURE) {
         return  FAILURE;
     }
 
     php_output_activate(TSRMLS_C);
     sapi_activate(TSRMLS_C);
     php_hash_environment(TSRMLS_C);
 
     zend_try {
         PG(during_request_startup) = 1;
         if  (PG(expose_php)) {
             sapi_add_header(SAPI_PHP_VERSION_HEADER,  sizeof (SAPI_PHP_VERSION_HEADER)-1, 1);
         }
     } zend_catch {
         retval = FAILURE;
     } zend_end_try();
 
     return  retval;
}



来看几个简化以后的主要函数:
zend_activate(TSRMLS_C); //激活zend引擎
zend_activate_modules(TSRMLS_C); //激活所有模块,使用for循环回调每个模块的 INIT_FUNC
php_output_activate(TSRMLS_C); //激活输出的堆栈结构, 就是声明了一个结构体,分配了空间
sapi_activate(TSRMLS_C); //激活当前这个sapi,主要是初始化一些常量,比如$_COOKIE
php_hash_environment(TSRMLS_C); //应该是hash存储的一些变量,没具体看


其实除了获取一些命令参数是从环境变量获取之外, 它的运行过程和CLI模式差不多,






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值