PHP的GET/POST等大变量生成过程

来源:互联网 发布:网络游戏服务端源码 编辑:程序博客网 时间:2024/06/07 04:59
可以去拜读一下,分析得挺详细的。自己再读了一下源代码,有了一些不同的心得,也顺便写下来。
首先要知道一点,$_GET,$_POST等变量的含义,即是在与web服务器结合的情况下才会有的变量,在PHP源文夹的main目录下面,有两个文件,php_variables.c,php_variables.h,从名字可以看出这主要是用来处理PHP的变量的一些定义及函数。
在头文件中定义了一个php_startup_auto_globals(TSRMLS_D)函数,
main/php_variables.h
void php_startup_auto_globals(TSRMLS_D);
在C文件里面最后几行有这个函数的定义:
void php_startup_auto_globals(TSRMLS_D)
{
    zend_register_auto_global("_GET", sizeof("_GET")-1, NULL TSRMLS_CC);
    zend_register_auto_global("_POST", sizeof("_POST")-1, NULL TSRMLS_CC);
    zend_register_auto_global("_COOKIE", sizeof("_COOKIE")-1, NULL TSRMLS_CC);
    zend_register_auto_global("_SERVER", sizeof("_SERVER")-1, php_auto_globals_create_server TSRMLS_CC);
    zend_register_auto_global("_ENV", sizeof("_ENV")-1, php_auto_globals_create_env TSRMLS_CC);
    zend_register_auto_global("_REQUEST", sizeof("_REQUEST")-1, php_auto_globals_create_request TSRMLS_CC);
    zend_register_auto_global("_FILES", sizeof("_FILES")-1, NULL TSRMLS_CC);
}
很显然是注册了这几个全局变量。查找一下 知道zend_register_auto_global函数在Zend/zend_compile文件里面定义的,

int zend_register_auto_global(char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC)
{
    zend_auto_global auto_global;

    auto_global.name = zend_strndup(name, name_len);
    auto_global.name_len = name_len;
    auto_global.auto_global_callback = auto_global_callback;

    return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, sizeof(zend_auto_global), NULL);
}
主要是把这几个变量注册到_zend_compiler_globals结构体里面的auto_globals哈希表里面.关于HashTable的介绍看昨天发表的一篇文章Zend HashTable详解,结构体在zend/zend_globals.h里面定义.另外CG宏的定义如下:
# define CG(v) (compiler_globals.v),在zend/zend_globals_macros.h头文件定义

好了,现在知道了startup_auto_globals的主要作用,那么PHP是在什么时候去调用这个函数的呢。利用一些工具的“在文件中查找”的功能就很容易很找到这个函数出现在哪些文件中。个人用惯了editplus,也有用visualstudio。一搜就发现这个函数在main/main.c里面被调用了,而且是在php_module_startup这个函数里面调用的,在这个函数里面还做了很多其他工作,这些不是今天的内容暂时先跳过。从函数名中可以知道这个函数是在模块启动的时候做的一些初始化工作,好,继续寻找,这个函数是在什么地方被调用,再一搜出现了将近有20个结果,都是在sapi目录下面出现的,比如在sapi/apache/mod_php5.c文件里面,php_apache_startup这个函数调用了,作用也很明显了,就是在PHP作为apache模块启动时,PHP就去初始化这些变量。
另外关于PHP中的SAPI的概念,可以去阅读一下风雪之隅的一篇文章:深入理解Zend SAPIs(Zend SAPI Internals).
上面分析了那么一大段其实就是追踪了php_startup_auto_globals函数,它的作用只是在auto_globals的哈希表里面注册了这几个变量。对这几个变量做的初始化工作是通过调用php_hash_environment实现的。至于是如何实现的风雪之隅的文章已作了分析,想了解的可以去看看。