PHP核心中讀取$_GET\$_POST等全域變數

來源:互聯網
上載者:User

一、核心中擷取$_GET\$_POST\$_SERVER\$_FILES\$_COOKIE等全域變數
HashTable是PHP很多實現的基礎,例如$_GET\$_POST等全域變數實現。
那麼,在擴充中讀取這些全域變數,當然還是操作HashTable。
核心中初始化環境變數的通過main/php_variables.c中php_hash_environment(TSRMLS_D)

PHP在初始化環境變數的同時,考慮到對大變數的讀效能,會通過main/php_variables.c的php_startup_auto_globals來註冊一份唯讀環境變數。

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);}

唯讀環境變數的讀取方式:

&PG(http_globals)[TRACK_VARS_GET];&PG(http_globals)[TRACK_VARS_POST];&PG(http_globals)[TRACK_VARS_REQUEST];&PG(http_globals)[TRACK_VARS_COOKIE];&PG(http_globals)[TRACK_VARS_ENV];&PG(http_globals)[TRACK_VARS_FILES];

其中用到的宏為核心提供

/*main/php_globals.h*/#define TRACK_VARS_POST0#define TRACK_VARS_GET1#define TRACK_VARS_COOKIE2#define TRACK_VARS_SERVER3#define TRACK_VARS_ENV4#define TRACK_VARS_FILES5#define TRACK_VARS_REQUEST6

如果需要對環境變數進行修改,可以在全域範圍中搜尋:

(void)zend_hash_find(&EG(symbol_table), ZEND_STRS("_GET"), (void **)&carrier);(void)zend_hash_find(&EG(symbol_table), ZEND_STRS("_POST"), (void **)&carrier);(void)zend_hash_find(&EG(symbol_table), ZEND_STRS("_REQUEST"), (void **)&carrier);(void)zend_hash_find(&EG(symbol_table), ZEND_STRS("_COOKIE"), (void **)&carrier);(void)zend_hash_find(&EG(symbol_table), ZEND_STRS("_FILES"), (void **)&carrier);(void)zend_hash_find(&EG(symbol_table), ZEND_STRS("_ENV"), (void **)&carrier);

二、現在來看案例,定義一個類request,擁有方法getQuery與getPost.來讀取$_GET和$_POST

/* * fw_request.c * *  Created on: 2012-6-19 *      Author: jy */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "php_ini.h"#include "main/SAPI.h"#include "Zend/zend_exceptions.h"#include "Zend/zend_alloc.h"#include "php_fw.h"#include "fw_request.h"zend_class_entry *request;/** *class Request  {  public mixed  getLang ( void  );  public mixed  getQuery ( string  $name = NULL );} *///定義類方法的參數類型,使核心自動校正參數類型ZEND_BEGIN_ARG_INFO(getQueryArgs, 1)ZEND_ARG_INFO(0, name)ZEND_END_ARG_INFO()ZEND_BEGIN_ARG_INFO(getPostArgs, 1)ZEND_ARG_INFO(0, name)ZEND_END_ARG_INFO()ZEND_METHOD(request, getQuery){zval **carrier;zval *key, *ret;if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &key) == FAILURE){RETURN_FALSE;}ret = request_query(TRACK_VARS_GET, Z_STRVAL_P(key), Z_STRLEN_P(key) TSRMLS_CC);RETURN_ZVAL(ret, 0, NULL);}ZEND_METHOD(request, getPost){zval **carrier;zval *key, *ret;if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &key) == FAILURE){RETURN_FALSE;}ret = request_query(TRACK_VARS_POST, Z_STRVAL_P(key), Z_STRLEN_P(key) TSRMLS_CC);RETURN_ZVAL(ret, 0, NULL);}zend_function_entry functions_entry[] = {PHP_ME(request, getQuery, getQueryArgs, ZEND_ACC_PUBLIC)PHP_ME(request, getPost, getPostArgs, ZEND_ACC_PUBLIC)};ZEND_MINIT_FUNCTION(fw_request){zend_class_entry ce;INIT_CLASS_ENTRY(ce, "request", functions_entry);request = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);return SUCCESS;}/*定義request_query來完成核心中讀取$_GET\$_POST\$_SERVER\$_FILES\$_COOKIE\$_REQUEST其中只有$_REQUEST的值是可修改的*/zval * request_query(uint type, char * name, uint len TSRMLS_DC) {zval **carrier, **ret;zend_bool jit_initialization = (PG(auto_globals_jit) && !PG(register_globals) && !PG(register_long_arrays));switch (type) {case TRACK_VARS_POST:case TRACK_VARS_GET:case TRACK_VARS_FILES:case TRACK_VARS_COOKIE:carrier = &PG(http_globals)[type];break;case TRACK_VARS_ENV:if (jit_initialization) {zend_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC);}carrier = &PG(http_globals)[type];break;case TRACK_VARS_SERVER:if (jit_initialization) {zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC);}carrier = &PG(http_globals)[type];break;case TRACK_VARS_REQUEST:if (jit_initialization) {zend_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC);}(void)zend_hash_find(&EG(symbol_table), ZEND_STRS("_REQUEST"), (void **)&carrier);break;default:break;}if (!carrier || !(*carrier)) {zval *empty;MAKE_STD_ZVAL(empty);ZVAL_NULL(empty);return empty;}if (!len) {Z_ADDREF_P(*carrier);return *carrier;}if (zend_hash_find(Z_ARRVAL_PP(carrier), name, len + 1, (void **)&ret) == FAILURE) {zval *empty;MAKE_STD_ZVAL(empty);ZVAL_NULL(empty);return empty;}Z_ADDREF_P(*ret);return *ret;}

三、網頁訪問PHP測試

訪問網址http://localhost/test.php?get=test,這個網址由你本地環境決定

$_GET['test'] = "abc";$obj = new request();echo $obj->getQuery('test')."<br>";echo $obj->getPost('test');

輸出結果:
test

這也證明了,request_query讀取的是唯讀全域變數。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.