检测 PHP 变量是否为引用/引用

2022-08-30 16:43:15

PHP中有没有办法确定给定变量是引用另一个变量和/或被另一个变量引用?我理解,鉴于对 php.net 设置意味着“$a和$b在这里完全相等的评论,可能无法将检测”引用“和”引用来自“分开。$a不是指向$b,反之亦然。$a和$b指向同一个地方。$a=& $b"

如果无法确定给定变量是否是引用/引用,是否有一种通用方法来确定两个变量是否是彼此的引用?同样,对 php.net 的注释提供了用于进行此类比较的函数 - 尽管它涉及编辑其中一个变量并查看另一个变量是否受到类似影响。如果可能的话,我宁愿避免这样做,因为我正在考虑的一些变量大量使用魔法获取器/二传手。

此实例中请求的背景是编写调试函数以帮助详细查看结构。


答案 1

完整的工作示例:

function EqualReferences(&$first, &$second){
    if($first !== $second){
        return false;
    } 
    $value_of_first = $first;
    $first = ($first === true) ? false : true; // modify $first
    $is_ref = ($first === $second); // after modifying $first, $second will not be equal to $first, unless $second and $first points to the same variable.
    $first = $value_of_first; // unmodify $first
    return $is_ref;
}

$a = array('foo');
$b = array('foo');
$c = &$a;
$d = $a;

var_dump(EqualReferences($a, $b)); // false
var_dump(EqualReferences($b, $c)); // false
var_dump(EqualReferences($a, $c)); // true
var_dump(EqualReferences($a, $d)); // false
var_dump($a); // unmodified
var_dump($b); // unmodified

答案 2

您可以使用debug_zval_dump

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

$var = 'A';
echo countRefs($var); // 0

$ref =& $var;
echo countRefs($var); // 1

但是,从 PHP 5.4 开始,这将不再起作用,因为它们删除了引用支持的调用时间传递,并可能在较低版本上引发级别错误。E_STRICT

如果你想知道,上面的函数从何而来:你告诉我...我通过尝试得到了它。在我看来,它应该只有3(变量,我函数中的变量,传递给的变量),但我不太擅长PHP内部,似乎它在某个地方创建了另一个引用;)-4zend_debug_zval


推荐