diff --git a/src/Symfony/Component/VarDumper/Cloner/VarCloner.php b/src/Symfony/Component/VarDumper/Cloner/VarCloner.php index 9e50f23501154..9583cbf6c2577 100644 --- a/src/Symfony/Component/VarDumper/Cloner/VarCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/VarCloner.php @@ -42,11 +42,15 @@ protected function doClone($var) $currentDepth = 0; // Current tree depth $currentDepthFinalIndex = 0; // Final $queue index for current tree depth $minimumDepthReached = 0 === $minDepth; // Becomes true when minimum tree depth has been reached - $cookie = (object) []; // Unique object used to detect hard references + $cookie = (object) []; // Unique object used to detect hard references $a = null; // Array cast for nested structures $stub = null; // Stub capturing the main properties of an original item value // or null if the original value is used directly + if (\PHP_VERSION_ID >= 70400) { + $cookie = [$cookie]; + } + if (!self::$hashMask) { self::$gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable self::initHashMask(); @@ -86,8 +90,13 @@ protected function doClone($var) } foreach ($vals as $k => $v) { // $v is the original value or a stub object in case of hard references - $refs[$k] = $cookie; - if ($zvalIsRef = $vals[$k] === $cookie) { + + if (\PHP_VERSION_ID < 70400 || (($zvalIsRef = null !== $r = \ReflectionReference::fromArrayElement($vals, $k)) && (!$zvalIsRef = 2 < $r->getRefcount()) && \is_array($v))) { + $refs[$k] = $cookie; + $zvalIsRef = $vals[$k] === $cookie; + } + + if ($zvalIsRef) { $vals[$k] = &$stub; // Break hard references to make $queue completely unset($stub); // independent from the original structure if ($v instanceof Stub && isset($hardRefs[spl_object_hash($v)])) {