如何在PHP中检查变量是否通过引用传递

6

简单明了: 我想写一些代码来判断变量是否通过引用传递。 例如:

<?php
function isReference($variable) {
    //return TRUE if &$something was passed
    //return FALSE if $something was passed
}
$text = 'Anything';
$a = isReference(&$text); //return TRUE
$b = isReference($test); //return FALSE
?>

如果您好奇,为什么我需要它? 首先,我不喜欢留下未解决的问题。 其次,我正在通过编写一个类似于PDO的准备语句的mysqli扩展来增强自己的技能。如果有人知道PDO中bindParam和bindValue之间的区别,他们就知道这是一个解决办法。我可以只创建两个函数,但我想知道是否可能只用一个函数。

提前感谢您的帮助。


7
值得一提的是,5.3版本中“按引用传递”的函数调用方式已被弃用,并在5.4版本中被移除。你不应该在新代码中使用它,而且你的API肯定不应该依赖它的存在。 - lonesomeday
如果有一个函数可以实现这个功能,我想PDO会做到,对吧? - Niet the Dark Absol
也许PDO的创建者没有这样做的好理由...无论如何,我刚学到传递引用方式已被弃用,这非常有帮助。谢谢lonesomeday。 - user2511406
3个回答

6
这里有一种不使用debug_zval_dump函数的方法来完成它:
function isReference($variable) {
    $variable = array($variable);
    $arg = func_get_arg(0);
    $isRef = isset($arg[0]) && $arg === array($variable[0]);
    $variable = $variable[0];

    return $isRef;
}

注意:只有一个情况不适用于此方法:
$text = array(&$text); // although i don't see why such a structure could be used
isReference($text); // will wrongly return false

显然,您可以通过使用随机唯一密钥(而不是0)来绕过此限制。

0

在我的测试中,检查默认值似乎可以正常工作。显然,如果$t已经设置为'x',那么它将无法工作,但您可以将默认值更改为完全不太可能的值以解决此问题:

function test(&$t='x'){
   if($t!='x') $t = 2;
}
test();   echo $t;  //outputs: null
test($t); echo $t;  //outputs: 2

0

您可以使用 debug_zval_dump将内部zend值的字符串表示转储到输出:

function isRef(&$val) {
    ob_start();
    debug_zval_dump(&$val);
    $ret = ob_get_clean();
    preg_match('~refcount\((\d+)\)~', $ret, $matches);
    return $matches[1] - 4;
}

$var1 = 'Var1';
$var2 = &$var1; // passed by ref
if(isRef($var2)) echo 'Passed by ref';

但要注意 PHP - 5.4


有趣的想法,但我不能批准它。我在多个地方和版本中进行了检查,包括但不限于 onlinephpfunctions 网站。即使我让这段代码工作,isRef($var1) 返回 TRUE,而预期结果是 FALSE($var1 不是打字错误)。是的,我知道版本在这里有很大的影响。 - user2511406
1
是的,这不是一个适当的解决方案,我也不知道任何一个,但是有个想法,呵呵 :-) - The Alpha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接