8000 [VarDumper] fix dumping typed references from properties · symfony/symfony@fe83e0e · GitHub
[go: up one dir, main page]

Skip to content

Commit fe83e0e

Browse files
[VarDumper] fix dumping typed references from properties
1 parent 66e8ae9 commit fe83e0e

File tree

3 files changed

+82
-20
lines changed

3 files changed

+82
-20
lines changed

src/Symfony/Component/VarDumper/Cloner/VarCloner.php

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,29 +82,39 @@ protected function doClone($var)
8282
// $v is the original value or a stub object in case of hard references
8383

8484
if (\PHP_VERSION_ID >= 70400) {
85-
$zvalIsRef = null !== \ReflectionReference::fromArrayElement($vals, $k);
85+
$zvalRef = ($r = \ReflectionReference::fromArrayElement($vals, $k)) ? $r->getId() : null;
8686
} else {
8787
$refs[$k] = $cookie;
88-
$zvalIsRef = $vals[$k] === $cookie;
88+
$zvalRef = $vals[$k] === $cookie;
8989
}
9090

91-
if ($zvalIsRef) {
91+
if ($zvalRef) {
9292
$vals[$k] = &$stub; // Break hard references to make $queue completely
9393
unset($stub); // independent from the original structure
94-
if ($v instanceof Stub && isset($hardRefs[spl_object_id($v)])) {
95-
$vals[$k] = $refs[$k] = $v;
94+
if (\PHP_VERSION_ID >= 70400 ? null !== $vals[$k] = $hardRefs[$zvalRef] ?? null : $v instanceof Stub && isset($hardRefs[spl_object_id($v)])) {
95+
if (\PHP_VERSION_ID >= 70400) {
96+
$v = $vals[$k];
97+
} else {
98+
$refs[$k] = $vals[$k] = $v;
99+
}
96100
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
97101
++$v->value->refCount;
98102
}
99103
++$v->refCount;
100104
continue;
101105
}
102-
$refs[$k] = $vals[$k] = new Stub();
103-
$refs[$k]->value = $v;
104-
$h = spl_object_id($refs[$k]);
105-
$hardRefs[$h] = &$refs[$k];
106-
$values[$h] = $v;
106+
$vals[$k] = new Stub();
107+
$vals[$k]->value = $v;
107108
$vals[$k]->handle = ++$refsCounter;
109+
110+
if (\PHP_VERSION_ID >= 70400) {
111+
$hardRefs[$zvalRef] = $vals[$k];
112+
} else {
113+
$refs[$k] = $vals[$k];
114+
$h = spl_object_id($refs[$k]);
115+
$hardRefs[$h] = &$refs[$k];
116+
$values[$h] = $v;
117+
}
108118
}
109119
// Create $stub when the original value $v can not be used directly
110120
// If $v is a nested structure, put that structure in array $a
@@ -163,12 +173,17 @@ protected function doClone($var)
163173
unset($v[$gid]);
164174
$a = [];
165175
foreach ($v as $gk => &$gv) {
166-
if ($v === $gv) {
176+
if ($v === $gv && (\PHP_VERSION_ID < 70400 || !isset($hardRefs[\ReflectionReference::fromArrayElement($v, $gk)->getId()]))) {
167177
unset($v);
168178
$v = new Stub();
169179
$v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0];
170180
$v->handle = -1;
171-
$gv = &$hardRefs[spl_object_id($v)];
181+
if (\PHP_VERSION_ID >= 70400) {
182+
$gv = &$a[$gk];
183+
$hardRefs[\ReflectionReference::fromArrayElement($a, $gk)->getId()] = &$gv;
184+
} else {
185+
$gv = &$hardRefs[spl_object_id($v)];
186+
}
172187
$gv = $v;
173188
}
174189

@@ -270,10 +285,12 @@ protected function doClone($var)
270285
}
271286
}
272287

273-
if ($zvalIsRef) {
274-
$refs[$k]->value = $stub;
275-
} else {
288+
if (!$zvalRef) {
276289
$vals[$k] = $stub;
290+
} elseif (\PHP_VERSION_ID >= 70400) {
291+
$hardRefs[$zvalRef]->value = $stub;
292+
} else {
293+
$refs[$k]->value = $stub;
277294
}
278295
}
279296

src/Symfony/Component/VarDumper/Tests/Cloner/VarClonerTest.php

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -499,12 +499,55 @@ public function testPhp74()
499499
[p1] => 123
500500
[p2] => Symfony\Component\VarDumper\Cloner\Stub Object
501501
(
502-
[type] => 4
503-
[class] => stdClass
504-
[value] =>
502+
[type] => 1
503+
[class] =>
504+
[value] => Symfony\Component\VarDumper\Cloner\Stub Object
505+
(
506+
[type] => 4
507+
[class] => stdClass
508+
[value] =>
509+
[cut] => 0
510+
[handle] => %i
511+
[refCount] => 1
512+
[position] => 0
513+
[attr] => Array
514+
(
515+
)
516+
517+
)
518+
505519
[cut] => 0
506-
[handle] => %i
507-
[refCount] => 0
520+
[handle] => 1
521+
[refCount] => 1
522+
[position] => 0
523+
[attr] => Array
524+
(
525+
)
526+
527+
)
528+
529+
[p3] => Symfony\Component\VarDumper\Cloner\Stub Object
530+
(
531+
[type] => 1
532+
[class] =>
533+
[value] => Symfony\Component\VarDumper\Cloner\Stub Object
534+
(
535+
[type] => 4
536+
[class] => stdClass
537+
[value] =>
538+
[cut] => 0
539+
[handle] => %i
540+
[refCount] => 1
541+
[position] => 0
542+
[attr] => Array
543+
(
544+
)
545+
546+
)
547+
548+
[cut] => 0
549+
[handle] => 1
550+
[refCount] => 1
508551
[position] => 0
509552
[attr] => Array
510553
(

src/Symfony/Component/VarDumper/Tests/Fixtures/Php74.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ class Php74
66
{
77
public $p1 = 123;
88
public \stdClass $p2;
9+
public \stdClass $p3;
910

1011
public function __construct()
1112
{
1213
$this->p2 = new \stdClass();
14+
$this->p3 = &$this->p2;
1315
}
1416
}

0 commit comments

Comments
 (0)
0