for testing and deploying your application
for finding and fixing issues
for empowering human code reviews
<?php
namespace Yiranzai\Tools;
/**
* Class Zval
* @package Yiranzai\Tools
*/
class Zval
{
* @param $var
* @return bool
public static function isRef($var): bool
$info = self::getZvalRefCountInfo($var);
return (boolean)$info['is_ref'];
}
* @return mixed
public static function getRefCount($var)
return $info['refcount'];
public static function canCopyOnWrite($var): bool
return $info['is_ref'] === 0;
public static function canReferenceWithoutCopy($var): bool
return $info['is_ref'] === 1 || $info['refcount'] === 1;
* @return array
public static function getZvalRefCountInfo($var): array
ob_start();
xdebug_debug_zval($var);
$info = ob_get_clean();
preg_match('(: \(refcount=(\d+), is_ref=(\d+)\))', $info, $match);
return array('refcount' => (int)$match[1], 'is_ref' => (int)$match[2]);
* @param $a
* @param $b
public static function isRefto(&$a, &$b): bool
if ($a !== $b) {
return false;
$t = $a;
if ($r = ($b === ($a = 1))) {
$r = ($b === ($a = 0));
$a = $t;
return $r;
public static function isReferenceOf(&$a, &$b): bool
if (!self::isRef('a') || self::getZvalRefCountInfo('a') !== self::getZvalRefCountInfo('b')) {
$tmp = $a;
if (is_object($a) || is_array($a)) {
$a = 'test';
$ret = $b === 'test';
$a = $tmp;
} else {
$a = [];
$ret = $b === [];
return $ret;