検索
ホームページphp教程php手册PHP的GET/POST等大变量生成过程

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

Jun 13, 2016 am 10:34 AM
gethttpphppost著者変数大きい生成するプロセス

· 作者:laruence(http://www.laruence.com/)
· 本文地址:http://www.laruence.com/2008/11/07/581.html
· 转载请注明出处                                                  
主要探讨了PHP的大变量的生成过程。另外如果你注意到, 当在表单中提交的input的name中如果有点号的时候, 在PHP中会自动把点号处理成下划线。并且你很想知道这是为什么,在什么时候发生的? 呵呵,本文也就这个问题做了回答。
首先明确一个问题,PHP的变量名中是不能包含点号的。 但是为了处理表单中的点号命名,PHP就会自动把点号(.)转换成下划线(_)。
      要知道PHP是怎么处理的,首先我们要了解,$_GET, $_POST, $_COOKIE等变量的构造过程。
在每个请求到来以后,apache处理到response阶段的时候, 会将控制权交给PHP模块, PHP模块会在处理请求之前首先间接调用php_request_startup (具体调用序列是send_php -> apache_php_module_main ->php_request_startup, 关于这部门可以参看我前面的文章(PHP Life Cycle) , 在php_request_startup中:
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;
        php_output_activate(TSRMLS_C);
        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;
}


   注意其中的php_hash_environment(TSRMLS_C)函数调用 , 这个函数就是在请求处理前, 初始化请求相关的变量的函数。
  这个函数定义在: main/php_variables.c中 , 有兴趣的可以看看:
int
php_hash_environment(TSRMLS_D)
{
char*p;
        unsigned
char
_gpc_flags[5]={0,0,0,0,0};
        zend_bool
jit_initialization=(PG(auto_globals_jit)&& !PG(register_globals)&& !PG(register_long_arrays));
        struct
auto_global_record
{
char*name;
               uint
name_len;
               char*long_name;
               uint
long_name_len;
               zend_bool
jit_initialization;
        }
auto_global_records[]={
{
"_POST",sizeof("_POST"),"HTTP_POST_VARS",sizeof("HTTP_POST_VARS"),0
},
               {
"_GET",sizeof("_GET"),"HTTP_GET_VARS",sizeof("HTTP_GET_VARS"),0
},
               {
"_COOKIE",sizeof("_COOKIE"),"HTTP_COOKIE_VARS",sizeof("HTTP_COOKIE_VARS"),0
},
               {
"_SERVER",sizeof("_SERVER"),"HTTP_SERVER_VARS",sizeof("HTTP_SERVER_VARS"),1
},
               {
"_ENV",sizeof("_ENV"),"HTTP_ENV_VARS",sizeof("HTTP_ENV_VARS"),1
},
               {
"_FILES",sizeof("_FILES"),"HTTP_POST_FILES",sizeof("HTTP_POST_FILES"),0
},
        };
        size_t
num_track_vars=sizeof(auto_global_records)/sizeof(struct
auto_global_record);
        size_t
i;

        /* jit_initialization = 0; */
for
(i=0;i{
PG(http_globals)[i]=NULL;
        }
for
(p=PG(variables_order);p&& *p;p++)
{
switch(*p)
{
case
p:
                        case
P:
                                if
(!_gpc_flags[0]&& !SG(headers_sent)&&SG(request_info).request_method&& !strcasecmp(SG(request_info).request_method,"POST"))
{
sapi_module.treat_data(PARSE_POST,NULL,NULL
TSRMLS_CC);      /* POST Data */
_gpc_flags[0]=1;
                                       if
(PG(register_globals))
{
php_autoglobal_merge(&EG(symbol_table),Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST])
TSRMLS_CC);
                                       }
}
break;
                   ....以下省略,www.devdao.com:
}}}


   到了这里说个题外话, 就是在php.ini中, 可以使用variables_order来控制PHP是否生成某个大变量,已经大变量的生成顺序。
   关于顺序,就是说, 如果打开了auto_register_globals的情况下, 如果先处理p,后处理g,那么$_GET[a],就会覆盖$_POST[a];
   可以看到,离成功不远了,sapi_module.treat_data 也就是php_default_treat_data,
   在php_default_treat_data中,对于变量,都调用php_register_variable_safe来注册变量, 而php_register_variable_safe最终会调用php_register_variable_ex:
PHPAPI
void
php_register_variable_ex(char*var,zval*val,zval*track_vars_array
TSRMLS_DC)
{
char*p=NULL;
   char*ip;      /* index pointer */
char*index, *escaped_index=NULL;
   int
var_len,index_len;
   zval*gpc_element, **gpc_element_p;
   zend_bool
is_array=0;
   HashTable*symtable1=NULL;

   assert(var!=NULL);

   if
(track_vars_array)
{
symtable1=Z_ARRVAL_P(track_vars_array);
   }
else
if
(PG(register_globals))
{
symtable1=EG(active_symbol_table);
   }
if
(!symtable1)
{
/* Nothing to do */
zval_dtor(val);
        return;
   }
/*
     * Prepare variable name
     */
/* ignore leading spaces in the variable name */
while
(*var&& *var==
)
{
var++;
   }
/* ensure that we dont have spaces or dots in the variable name (not binary safe) */
//特别注意以下这段。。。。
for
(p=var; *p;p++)
{
if
(*p==
|| *p==.)
{
            *p=_;
        }
else
if
(*p==[)
{
is_array=1;
      &

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。