我在开发PHP扩展时偶然发现了一个有趣的案例。在扩展码中我有:
PHP_FUNCTION(foo)
{
....
php_debug_zval_dump(return_value, 1);
}
在PHP代码中:
$v = foo();
debug_zval_dump($v);
当运行以上内容时,我得到:
string(19) "Mouse configuration" refcount(1)
NULL refcount(2)
扩展没有正确传递值的原因是什么?
谢谢!
这并不奇怪。
例如,如果执行return_value = some_string_zval;
,则只更改局部变量。php_debug_zval_dump
会起作用,但在函数之外不会产生任何影响。你必须主动复制zval,例如:
ZVAL_COPY_VALUE(return_value, my_string_zval_p);
zval_copy_ctor(return_value);
唯一可以从内部函数返回的情况是,仅复制指针而不是复制数据,如果该函数通过引用返回。在这种情况下,您将获得一个zval**
。
您得到一个NULL,因为debug_zval_dump()有一个内置的echo功能,并且您不能将echo设置为变量。所以你的$v=foo()实际上给了你$v="。空变量的refcount为2的原因是固有的PHP优化。
请在此处阅读:http://us3.php.net/manual/en/function.debug-zval-dump.php
因此,为了正确地返回您的价值,您可以:
- 通过将回显写入缓冲区来抑制内置回显
- 将缓冲区结果设置为变量
- 对该(非NULL)变量运行第二个debug_zval_dump()
以下是它的工作原理:
function myfunc($foo)
{
debug_zval_dump($foo, 1);
}
ob_start();
/*
starts the output buffer which will catch all code instead of echoing it to page
*/
myfunc('Mouse configuration');
$v = ob_get_contents();
/*
writes the buffer which contains your f(x) results to a var
*/
ob_end_clean();//clears the buffer
debug_zval_dump($v);//will echo non-null value
代码的结果是:
string(65)"string(19)"鼠标配置"refcount(3)long(1)refcount(1)"refcount(2)
我不知道这个代码意味着什么,但祝你好运。:)