以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