在PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究
来源:互联网 发布:软件销售总监 编辑:程序博客网 时间:2024/04/27 23:23
· 本文地址: http://www.laruence.com/2008/04/04/17.html
· 转载请注明出处
最近在做一个PHP的安全模块,其中要在Module的函数中获取用户的Cookie,从而生成签名;今天找遍Baidu/Google,一点相关资料都没有,不得已,只好给yahoo PHP dev mail list发了求救信。后来,偶然在Google上看到了一个变量 http_globals ,眼前一亮,虽然没有详细资料,但经过一顿试,N次Segmentation fault以后,终于成功!
接下来,我结合实例和大家分享:
假设要获取$_GET['c'];
首先,先介绍下http_globals;
1.http_globals,定义在php_globals.h中;
zval * http_globals[6];
其中的索引为:
#define TRACK_VARS_POST 0
#define TRACK_VARS_GET 1
#define TRACK_VARS_COOKIE 2
#define TRACK_VARS_SERVER 3
#define TRACK_VARS_ENV 4
#define TRACK_VARS_FILES 5
#define TRACK_VARS_REQUEST 6
就是不知道为什么,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 = 2, r_len,duplicate=1;
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-1)])->http_globals);
HASH_OF也是个宏,定义在zend_API.h中:
#define HASH_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:
1. php.h: #define PHP_FUNCTION ZEND_FUNCTION
2. zend_API.h: #define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
3. zend_API.h: #define ZEND_FN(name) zif_##name
4. zend_API.h: #define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
5. zend.h: #define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
这样一来,我们的函数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;
ulong ikey;
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=0 ; i<count; i++){
zend_hash_get_current_data(h, (void**)&data);
zend_hash_get_current_key(h, &skey, &ikey, 0);
add_assoc_stringl(return_value, skey, Z_STRVAL_PP(data), Z_STRLEN_PP(data), 1);
zend_hash_move_forward(h);
}
return;
// RETURN_STRINGL(strg, len, 0);
//ZVAL_STRINGL(return_value, strg, len, 0);
}
最后,欢迎来信交流
- 在PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究
- 在PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究
- php 获取提交的数据 $_REQUEST = $_GET + $_POST + $_COOKIE
- PHP 中 $_REQUEST、$_GET、$_POST、$_COOKIE 的关系和区别
- PHP 中 GPC的思考:$_REQUEST、$_GET、$_POST、$_COOKIE 的关系和区别
- PHP中全局变量$_REQUEST、 $_GET、 $_POST、 $_COOKIE 的关系和区别
- PHP中全局变量$_REQUEST、 $_GET、 $_POST、 $_COOKIE 的关系和区别 (转载)
- php $_GET $_POST $_COOKIE取值过程
- PHP 里面$_REQUEST 包含 $_GET,$_POST,$_COOKIE
- PHP中,$_request 、$_post 、$_get的区别
- php中$_Get与$_POST的区别
- php中$_REQUEST、$_POST、$_GET的区别
- php 自动全局变量 $_SERVER,$_ENV,$_COOKIE,$_GET,$_POST,$_FILES,$_SESSION
- PHP 获取表单提交的数据($_GET $_POST)
- get_magic_quotes_gpc() 对$_GET $_COOKIE $_POST转义处理
- php中$_request与$_post、$_get的区别
- php中$_request与$_post、$_get的区别
- php中$_REQUEST与$_POST、$_GET的区别
- OpenID资源大全
- 开始学习java--设置Path与Classpath(《Java学习笔记》)[摘录]
- 由Signal想到的
- 如何使状态栏看起来有下沉的风格
- 父亲的信
- 在PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究
- 开发PHP扩展-提供一个可以被PHP使用的类
- 微软策略
- 如何学好JAVA语言?
- face2,让你的网站拥有像Google一样的智能提示
- JDK路径设置全解
- 十个忠告
- 解决cron不执行的问题
- var_export 和 var_dump对Resource类型的区别