PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究
假设要获取$_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)展开后就会成为:
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中:
#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<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的方法研究的更多相关文章
- idea中复制module和module中的蓝色tag出现的方法
1.在从github上面导入项目到idea中时,经常好多module都是没有蓝色的tag的,这说明这不是个maven形式的module,需要导入到项目中. 举个例子: 有蓝色tag的module才可以 ...
- Halcon中缩放Region或XLD的方法研究
在Halcon中,Region和XLD之间可以彼此转换.但这种转换并不是“无损”的,XLD可以是不闭合的,但是Region一定是闭合的.因此,如果将不闭合的XLD转为Region,然后再转回XLD,那 ...
- python中引入包的时候报错AttributeError: module 'sys' has no attribute 'setdefaultencoding'解决方法?
python中引入包的时候报错:import unittestimport smtplibimport timeimport osimport sysimp.reload(sys)sys.setdef ...
- 在function module 中向数据库插入数据
http://www.sapjx.com/abap-function-module.html 1: 应该在function module 中向数据库插入数据
- (转)关于ES6的 模块功能 Module 中export import的用法和注意之处
关于ES6的 模块功能 Module 中export import的用法和注意之处 export default 的用法 export default命令用于指定模块的默认输出.显然,一个模块只能有一 ...
- SpringMVC 项目中引用其他 Module 中的方法
1. 将要引用的Module 引入项目中 2. 在主Module中添加依赖, 3. 被引用的类必须放在 Module 中/src/下的某个package中,否则引用不到(重要)
- Python module中的全局变量
Python module中的全局变量 我想要实现一个python module,这个module中有一些配置项,这些配置项可以被读取,被修改.一个可行的方案是把这些配置项写到一个叫settings. ...
- Vuex入门实践(中)-多module中的state、mutations、actions和getters
一.前言 上一篇文章<Vuex入门实践(上)>,我们一共实践了vuex的这些内容: 1.在state中定义共享属性,在组件中可使用[$store.state.属性名]访问共享属性 2.在m ...
- AngularJS进阶(三十三)书海拾贝之简介AngularJS中使用factory和service的方法
简介AngularJS中使用factory和service的方法 AngularJS支持使用服务的体系结构"关注点分离"的概念.服务是JavaScript函数,并负责只做一个特定的 ...
随机推荐
- [主席树]HDOJ3874 Necklace
题意:n个数 m个询问 询问的是[l, r]区间内不同的数的和 没有修改,静态的主席树即可 与 SPOJ QUERY 一样 将重复的元素建树即可 注意范围:$N \le 50000$ 每个值不超过1 ...
- Project Euler 92:Square digit chains 平方数字链
题目 Square digit chains A number chain is created by continuously adding the square of the digits in ...
- lintcode:Find the Connected Component in the Undirected Graph 找出无向图汇总的相连要素
题目: 找出无向图汇总的相连要素 请找出无向图中相连要素的个数. 图中的每个节点包含其邻居的 1 个标签和 1 个列表.(一个无向图的相连节点(或节点)是一个子图,其中任意两个顶点通过路径相连,且不与 ...
- C编译过程概述
转自:http://my.oschina.net/apeng/blog/105245 C 编译过程概述 目前Linux下最常用的C语言编译器是GCC(GNU Compiler Collection), ...
- ADO.NET入门教程(二)了解.NET数据提供程序
出处:http://www.cnblogs.com/liuhaorain/archive/2012/02/11/2346312.html 1. 什么是.NET数据提供程序? .NET Framewor ...
- 构建linux内核源码树
编写驱动程序时,需要内核源码树的支持.内核源码树时从内核源代码编译得到的.下面开始构造内核源代码的步骤.以Ubuntu为例子 1. 下载内源代码,位置www.kernel.org. (注意:源码树内核 ...
- NDK xxxxx could not be resolved解决方法
Type '*****' could not be resolved Method '******' could not be resolved 问题解决 以下为未尝试方法,如果上面方法解 ...
- Linux系统下统计目录及其子目录文件个数
(1)查看某目录下文件的个数: ls -l |grep "^-"|wc -l 或 find ./company -type f | wc -l (2)查看某目录下文件的个数,包括子 ...
- 面试题_31_to_47_JVM 底层与GC(Garbage Collection)的面试问题
31)64 位 JVM 中,int 的长度是多数?Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位.意思就是说,在 32 位 和 64 位 的Java 虚拟机中,int 类 ...
- poj 1151 Atlantis (离散化 + 扫描线 + 线段树 矩形面积并)
题目链接题意:给定n个矩形,求面积并,分别给矩形左上角的坐标和右上角的坐标. 分析: 映射到y轴,并且记录下每个的y坐标,并对y坐标进行离散. 然后按照x从左向右扫描. #include <io ...