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

bor*_*ble 24 php php-internals

在PHP中是否有办法确定给定变量是否是对另一个变量的引用和/或是否由另一个变量引用?我感谢可能无法将检测"引用"和"引用"分开,因为php.net上的注释设置$a=& $b意味着" $ a和$ b在这里完全相同.$ a不指向$ b或者反之亦然.$ a和$ b指向同一个地方. "

如果无法确定给定变量是否为引用/引用,是否有一种通用的方法来确定两个变量是否是彼此的引用?同样,对php.net 的评论提供了进行这种比较的函数 - 尽管它涉及编辑其中一个变量并查看其他变量是否同样受影响.如果可能的话,我宁愿避免这样做,因为我正在考虑的一些变量大量使用魔法吸气剂/设定器.

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

Nik*_*kiC 6

你可以使用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
Run Code Online (Sandbox Code Playgroud)

这虽然不再适用于PHP 5.4,因为它们通过引用支持删除了调用时间,并且可能会E_STRICT在较低版本上引发级别错误.

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


Pac*_*ier 5

完整的工作示例:

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
Run Code Online (Sandbox Code Playgroud)