Search code examples
phpphp-internals

Detecting whether a PHP variable is a reference / referenced


Is there a way in PHP to determine whether a given variable is a reference to another variable and / or referenced by another variable? I appreciate that it might not be possible to separate detecting "reference to" and "reference from" given the comment on php.net that setting $a=& $b means "$a and $b are completely equal here. $a is not pointing to $b or vice versa. $a and $b are pointing to the same place."

If it's not possible to determine whether a given variable is a reference / referenced, is there a generalised way of determining if two variables are references of each other? Again, a comment on php.net supplies a function for doing such a comparison - although it is one that involves editing one of the variables and seeing if the other variable is similarly effected. I'd rather avoid doing this if possible since some of the variables I'm considering make heavy use of magic getters / setters.

The background to the request in this instance is to write a debugging function to help view structures in detail.


Solution

  • You can use 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
    

    This though will not work anymore as of PHP 5.4 as they removed call time pass by reference support and may throw an E_STRICT level error on lower versions.

    If you wonder, where the -4 in the above function come from: You tell me... I got it by trying. In my eyes it should be only 3 (the variable, the variable in my function, the variable passed to zend_debug_zval), but I'm not too good at PHP internals and it seems that it creates yet another reference somewhere on the way ;)