PHP 扩展函数返回的值为 NULL

发布于 2024-11-17 06:40:28 字数 363 浏览 2 评论 0原文

我在开发 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)

值未从扩展正确传递的原因是什么?

谢谢!

I've stumbled upon an interesting case while developing an extension for PHP. In the extension code I have:

PHP_FUNCTION(foo)
{
   ....
   php_debug_zval_dump(return_value, 1);
}

In the PHP code:

$v = foo();
debug_zval_dump($v);

When running the above, I get:

string(19) "Mouse configuration" refcount(1)
NULL refcount(2)

What can be the reason that the value isn't passed properly from the extension?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

执笔绘流年 2024-11-24 06:40:28

这并不奇怪。

例如,如果您执行了 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**

It's not that strange.

For instance, if you did return_value = some_string_zval; you would be changing only the local variable. php_debug_zval_dump would work, but it would have no effect outside the function. You have to actively copy the zval, e.g. with:

ZVAL_COPY_VALUE(return_value, my_string_zval_p);
zval_copy_ctor(return_value);

The only case you could return from an internal function merely copying a pointer instead of copying data was if that function returned by reference. In that case, you're given a zval**.

情徒 2024-11-24 06:40:28

您得到 NULL 是因为 debug_zval_dump() 具有内置回显功能,并且您无法将回显设置为变量。所以你的 $v = foo() 实际上给你 $v = ""。空变量的引用计数为 2 的原因是由于固有的 PHP 优化。

在这里阅读相关内容: https://www.php.net /manual/en/function.debug-zval-dump.php

因此,要正确返回您的值,您可以:

  1. 通过将回显写入缓冲区来抑制内置回显 将
  2. 缓冲区结果设置为变量
  3. 运行第二个debug_zval_dump() 对此(not NULL) 变量

以下是它的工作原理:

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) "Mouse configuration" refcount(3) long(1) refcount(1) " refcount(2)

我不知道这段代码的用途是什么,但无论如何,祝你好运。 :)

You're getting a NULL because debug_zval_dump() has a built-in echo feature and you cannot set an echo to a variable. So your $v = foo() is actually giving you $v = "". The reason you're getting a refcount of 2 for an empty variable is because of inherent PHP optimization.

Read about that here: https://www.php.net/manual/en/function.debug-zval-dump.php

So to return your value properly you can:

  1. Suppress the built-in echo by writing the echo to a buffer
  2. Set the buffer result to a variable
  3. Run your second debug_zval_dump() on that (not NULL) variable

Here's how it works:

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

The code will result with this:

string(65) "string(19) "Mouse configuration" refcount(3) long(1) refcount(1) " refcount(2)

I have no idea what this code is meant to do but Good Luck anyways. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文