以xdebug_debug_zval()为顶点。现在,这是真正知道您是否可以确定有关变量zval的所有内容的唯一方法。
所以这里有一对夫妇的辅助功能,以确定一些有用的信息:
function isRef($var) {
$info = getZvalRefCountInfo($var);
return (boolean) $info['is_ref'];
}
function getRefCount($var) {
$info = getZvalRefCountInfo($var);
return $info['refcount'];
}
function canCopyOnWrite($var) {
$info = getZvalRefCountInfo($var);
return $info['is_ref'] == 0;
}
function canReferenceWithoutCopy($var) {
$info = getZvalRefCountInfo($var);
return $info['is_ref'] == 1 || $info['refcount'] == 1;
}
function getZvalRefCountInfo($var) {
ob_start();
xdebug_debug_zval($var);
$info = ob_get_clean();
preg_match('(: \(refcount=(\d+), is_ref=(\d+)\))', $info, $match);
return array('refcount' => $match[1], 'is_ref' => $match[2]);
}
一些样品变量
所以:
$a = 'test';
$b = $a;
$c = $b;
$d =& $c;
$e = 'foo';
我们可以测试一个变量的引用:
isRef('a'); // false
isRef('c'); // true
isRef('e'); // false
我们可以得到链接到zval的变量的数量(不一定是引用,可以是对于写入时复制):
getRefCount('a'); // 2
getRefCount('c'); // 2
getRefCount('e'); // 1
我们可以测试我们可以写入时复制(没有副本进行内存复制):
canCopyOnWrite('a'); // true
canCopyOnWrite('c'); // false
canCopyOnWrite('e'); // true
我们可以测试我们可以做而不复制的zval的引用:现在
canReferenceWithoutCopy('a'); // false
canReferenceWithoutCopy('c'); // true
canReferenceWithoutCopy('e'); // true
而且,我们可以检查,如果一个变量引用本身通过一些魔法:
function isReferenceOf(&$a, &$b) {
if (!isRef('a') || getZvalRefCountInfo('a') != getZvalRefCountInfo('b')) {
return false;
}
$tmp = $a;
if (is_object($a) || is_array($a)) {
$a = 'test';
$ret = $b === 'test';
$a = $tmp;
} else {
$a = array();
$ret = $b === array();
$a = $tmp;
}
return $tmp;
}
这有点不好意思,因为我们无法确定其他符号引用相同的zval(只有其他符号引用)。因此,这基本上检查是否$a
是一个参考,并且如果$a
和$b
都具有相同的引用计数和引用标志设置。然后,它会更改一个以检查其他更改(表明它们是相同的参考)。
您可以检查两个变量是相互的引用:http://stackoverflow.com/a/18110347/632951 – Pacerier 2013-08-07 17:55:15