假设要获取$_GET['c']; 首先,先介绍下http_globals;

1.http_globals,定义在php_globals.h中; zval * http_globals[6]; 其中的索引为:

 #defineTRACK_VARS_POST
#defineTRACK_VARS_GET
#defineTRACK_VARS_COOKIE
#defineTRACK_VARS_SERVER
#defineTRACK_VARS_ENV
#defineTRACK_VARS_FILES
#defineTRACK_VARS_REQUEST

就是不知道为什么,http_globals定义为6个元素,但是索引却定义了7个,猜测可能是因为REQUREST本来也就是GET和POST的 merge,并且存取都是通过宏来进行,所以可能最后宏中会处理TRACK_VARS_REQUEST为GET和POST的merge。

2.获取方法:

 zval * arr;
zval ** temp;
char * key = "c", r_str;
int len = , r_len,duplicate=;
arr = PG(http_globals)[TRACK_VARS_GET];
zend_hash_find(HASH_OF(arr), key, len, (void **)&temp);
r_str = Z_STRVAL_PP(temp);
r_len = Z_STRLEN_PP(temp);
ZVAL_STRINGL(return_value, r_str, r_len, duplicate)

3.分析 其中PG是一个宏,定义在php_globals.h中: # define PG(v) TSRMG(core_globals_id, php_core_globals *, v) 而TSRMG也是一个宏,定义在TSRM.h中: #define TSRMG(id, type, element) (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element) 而TSRM_UNSHUFFLE_RSRC_ID也是一个宏,也定义在TSRM.h中: #define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)

那么PG(http_globals)展开后就会成为:

  1.  PG(http_globals) =>;
    TSRM(core_globals_id, php_core_globals *, http_globals);
    =>;
    ((php_core_globals *)(*((void ***))tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(core_globals_id)])->http_globals);
    =>;
    ((php_core_globals *)(*((void ***))tsrm_ls))[(core_globals_id-)])->http_globals);

HASH_OF也是个宏,定义在zend_API.h中:

  1.  #defineHASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p) TSRMLS_CC) : NULL)))

4.获取 根据测试的结果,可以认定PG(http_globals)[TRACK_VARS_GET]是一个hash table;

5.问题 有个问题就是,Zend中好像字符的len要计算结束符’\0′的,就是因为我定义len=1,导致crash N次。。郁闷。

6.再补充点关于return_value:

 php.h: #definePHP_FUNCTIONZEND_FUNCTION
zend_API.h: #defineZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
zend_API.h: #defineZEND_FN(name) zif_##name
zend_API.h: #defineZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
zend.h: #defineINTERNAL_FUNCTION_PARAMETERS int ht, zval*return_value, zval**return_value_ptr, zval*this_ptr, int return_value_usedTSRMLS_DC</blockquote>

这样一来,我们的函数PHP_FUNCTION(getGetParam)就会变成: void zif_getGetParam( int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC);

可见,return_value是默认就定义的,是返回值的载体。

呵呵,就写这么多,有时间再补充。

7.原代码:

 PHP_FUNCTION(confirm_getCookie_compiled){
char *arg = NULL;
int arg_len, len;
ulongikey;
char * strg, * skey;
zval * arr;
zval**data;
HashTable* h;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
WRONG_PARAM_COUNT;
}
arr = PG(http_globals)[TRACK_VARS_GET];
h = HASH_OF(arr);
array_init(return_value);
zend_hash_internal_pointer_reset(h);
int count = zend_hash_num_elements(h);
for(int i= ; i&lt;count; i++){
zend_hash_get_current_data(h, (void**)&data);
zend_hash_get_current_key(h, &skey, &ikey, );
add_assoc_stringl(return_value, skey, Z_STRVAL_PP(data), Z_STRLEN_PP(data), );
zend_hash_move_forward(h);
}
return;
// RETURN_STRINGL(strg, len, 0);
//ZVAL_STRINGL(return_value, strg, len, 0);
}

文章出处: http://www.laruence.com/2008/04/04/17.html

PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究的更多相关文章

  1. idea中复制module和module中的蓝色tag出现的方法

    1.在从github上面导入项目到idea中时,经常好多module都是没有蓝色的tag的,这说明这不是个maven形式的module,需要导入到项目中. 举个例子: 有蓝色tag的module才可以 ...

  2. Halcon中缩放Region或XLD的方法研究

    在Halcon中,Region和XLD之间可以彼此转换.但这种转换并不是“无损”的,XLD可以是不闭合的,但是Region一定是闭合的.因此,如果将不闭合的XLD转为Region,然后再转回XLD,那 ...

  3. python中引入包的时候报错AttributeError: module 'sys' has no attribute 'setdefaultencoding'解决方法?

    python中引入包的时候报错:import unittestimport smtplibimport timeimport osimport sysimp.reload(sys)sys.setdef ...

  4. 在function module 中向数据库插入数据

    http://www.sapjx.com/abap-function-module.html 1: 应该在function module 中向数据库插入数据

  5. (转)关于ES6的 模块功能 Module 中export import的用法和注意之处

    关于ES6的 模块功能 Module 中export import的用法和注意之处 export default 的用法 export default命令用于指定模块的默认输出.显然,一个模块只能有一 ...

  6. SpringMVC 项目中引用其他 Module 中的方法

    1. 将要引用的Module 引入项目中 2. 在主Module中添加依赖, 3. 被引用的类必须放在 Module 中/src/下的某个package中,否则引用不到(重要)

  7. Python module中的全局变量

    Python module中的全局变量 我想要实现一个python module,这个module中有一些配置项,这些配置项可以被读取,被修改.一个可行的方案是把这些配置项写到一个叫settings. ...

  8. Vuex入门实践(中)-多module中的state、mutations、actions和getters

    一.前言 上一篇文章<Vuex入门实践(上)>,我们一共实践了vuex的这些内容: 1.在state中定义共享属性,在组件中可使用[$store.state.属性名]访问共享属性 2.在m ...

  9. AngularJS进阶(三十三)书海拾贝之简介AngularJS中使用factory和service的方法

    简介AngularJS中使用factory和service的方法 AngularJS支持使用服务的体系结构"关注点分离"的概念.服务是JavaScript函数,并负责只做一个特定的 ...

随机推荐

  1. [主席树]HDOJ3874 Necklace

    题意:n个数 m个询问 询问的是[l, r]区间内不同的数的和 没有修改,静态的主席树即可 与 SPOJ QUERY 一样 将重复的元素建树即可 注意范围:$N \le  50000$ 每个值不超过1 ...

  2. Project Euler 92:Square digit chains 平方数字链

    题目 Square digit chains A number chain is created by continuously adding the square of the digits in ...

  3. lintcode:Find the Connected Component in the Undirected Graph 找出无向图汇总的相连要素

    题目: 找出无向图汇总的相连要素 请找出无向图中相连要素的个数. 图中的每个节点包含其邻居的 1 个标签和 1 个列表.(一个无向图的相连节点(或节点)是一个子图,其中任意两个顶点通过路径相连,且不与 ...

  4. C编译过程概述

    转自:http://my.oschina.net/apeng/blog/105245 C 编译过程概述 目前Linux下最常用的C语言编译器是GCC(GNU Compiler Collection), ...

  5. ADO.NET入门教程(二)了解.NET数据提供程序

    出处:http://www.cnblogs.com/liuhaorain/archive/2012/02/11/2346312.html 1. 什么是.NET数据提供程序? .NET Framewor ...

  6. 构建linux内核源码树

    编写驱动程序时,需要内核源码树的支持.内核源码树时从内核源代码编译得到的.下面开始构造内核源代码的步骤.以Ubuntu为例子 1. 下载内源代码,位置www.kernel.org. (注意:源码树内核 ...

  7. NDK xxxxx could not be resolved解决方法

    Type '*****' could not be resolved Method '******' could not be resolved     问题解决   以下为未尝试方法,如果上面方法解 ...

  8. Linux系统下统计目录及其子目录文件个数

    (1)查看某目录下文件的个数: ls -l |grep "^-"|wc -l 或 find ./company -type f | wc -l (2)查看某目录下文件的个数,包括子 ...

  9. 面试题_31_to_47_JVM 底层与GC(Garbage Collection)的面试问题

    31)64 位 JVM 中,int 的长度是多数?Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位.意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类 ...

  10. poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)

    题目链接题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标. 分析: 映射到y轴,并且记录下每个的y坐标,并对y坐标进行离散. 然后按照x从左向右扫描. #include <io ...