Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将哈希表数据从php.ini传递到扩展方法:损坏的值_Php_C_Hashtable_Php 7_Php Internals - Fatal编程技术网

将哈希表数据从php.ini传递到扩展方法:损坏的值

将哈希表数据从php.ini传递到扩展方法:损坏的值,php,c,hashtable,php-7,php-internals,Php,C,Hashtable,Php 7,Php Internals,我试图使PHP(7.4)扩展在扩展方法中使用一个从PHP.ini(比如myext.map=key1=val1,key2=val2;)解析为关联数组的设置。我希望解析在PHP\u MINIT\u函数(myext)中进行 因此,我声明了一个php设置,未注释的REGISTER_INI_ENTRIES()在PHP\u MINIT\u函数(myext)中声明: ZEND_BEGIN_MODULE_GLOBALS(myext) HashTable map; ZEND_END_MODULE_GLOB

我试图使PHP(7.4)扩展在扩展方法中使用一个从
PHP.ini
(比如
myext.map=key1=val1,key2=val2;
)解析为关联数组的设置。我希望解析在
PHP\u MINIT\u函数(myext)
中进行

因此,我声明了一个php设置,未注释的
REGISTER_INI_ENTRIES()
PHP\u MINIT\u函数(myext)
中声明:

ZEND_BEGIN_MODULE_GLOBALS(myext)
    HashTable map;
ZEND_END_MODULE_GLOBALS(myext)
并从
php.ini
settingJR:

PHP_INI_MH(myext_update_map) {
// The part that parses new_value into (key => val) pairs is skipped. It works.
//...
// key = val assignments have been counted.
zend_hash_init(&MYEXT_G(map), count, NULL, NULL, 1); // 1 for "persistent".
// ...
// Iterating (key => value) pairs.
    // key, key_len, val, val_len have been successfully extracted from php.ini.
    zend_string * key_z = zend_string_init( key, key_len, 1 );
    zval val_z;
    ZVAL_STRINGL( &val_z, val, val_len );
    zend_hash_add_new( &MYEXT_G(map), key_z, &val_z );
然后,在PHP方法中,我尝试从&MYEXT_G(map)读取数据:

如果从命令行调用包含
MyExt::getLibraries()
的PHP脚本,PHP警告将打印在
PHP.ini
中设置的键和值

但是,如果通过HTTP请求调用脚本,则在警告消息中,
ZSTR_VAL(key_z)
是正确的,但是
z_STRVAL_p(VAL_z)
z_STRLEN_p(VAL_z)
都包含垃圾

所有涉及的函数要么定义为PHP宏,要么接收
TSRMLS\u DC

全局哈希表中的值(而不是键)似乎在模块初始化和服务HTTP请求之间被释放

我已经确保
MYEXT\u G
中的标量值从
PHP\u MINIT\u函数(MYEXT)
保存到从HTTP请求调用的PHP方法中

那么,如何确保
HashTable
值是真正持久的呢?

正如我在PHP内部的建议一样(internals@lists.php.net),
ZVAL_STRINGL
为每个请求字符串分配一个字符串;我需要
ZVAL_STR
ZVAL_STR(&val_z,zend_string_init(val,val_len,1))

然后我将
val_z
添加到全局哈希表中:
zend_hash_str_add_new(&MYEXT_G(map)、key_z、key_len和val_z)。提供HTTP请求时,哈希表
&MYEXT_G(map)
是可读的(键和值)

PHP_METHOD(MyExt, getMap) {
// ...
zend_string * key_z;
zval * val_z;
ZEND_HASH_FOREACH_STR_KEY_VAL(&MYEXT_G(map), key_z, val_z)
    php_error_docref( NULL TSRMLS_CC, E_WARNING, "ZSTR_VAL(key_z) = %s\n", ZSTR_VAL(key_z) );
    php_error_docref( NULL TSRMLS_CC, E_WARNING, "Z_STRVAL_P(val_z) = %s\n", Z_STRVAL_P(val_z) );
    php_error_docref( NULL TSRMLS_CC, E_WARNING, "Z_STRLEN_P(val_z) = %lu\n", Z_STRLEN_P(val_z) );
ZEND_HASH_FOREACH_END();