PHP SAPI(CGI)个人整理

来源:互联网 发布:二战英国巡洋舰知乎 编辑:程序博客网 时间:2024/06/14 08:42
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模式差不多,






原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宽带ip地址改了怎么办 移动宽带恢复出厂设置了怎么办 移动100兆网速慢怎么办 手机显示无法解析dns地址怎么办 台式电脑宽带连接不上怎么办 电信宽带账号登录密码忘记了怎么办 电信校园宽带超时了怎么办 宽带连接账号密码忘了怎么办 移动宽带路由器上不了网怎么办 移动宽带太卡了怎么办 电信adsl密码忘记了怎么办 移动宽带无法连接网络怎么办 移动宽带电视无信号怎么办 联通网线故障电话打不通怎么办 w10系统ip地址错误怎么办 移动流量太贵了怎么办 修改wifi密码ip地址怎么办 苹果6s接电话声音小怎么办 k歌录音器失败怎么办 想报警但不能说话怎么办 微粒贷要家人电话怎么办 4g网络信号差怎么办 手机移动网络信号不好怎么办 移动的4g网络差怎么办 4g移动网络慢怎么办 房间没有4g网络怎么办 oppo显示2g网络怎么办 oppo只有2g网络怎么办 移动卡4g网络慢怎么办 易信专线电话用完了怎么办 手机拨打电话时黑屏怎么办 网易号文章一直审核中怎么办 登陆积分会员忘记密码怎么办 易信密码忘记了怎么办 滴滴永久封停的号怎么办 微信版本过低怎么办 报关时通关单号没录怎么办 公司注销了行政许可证怎么办呢 报关项数超过50项怎么办 出口报关件数报多了怎么办 关税少交被海关缉私查到怎么办