Skip to content

Commit 2627c16

Browse files
bug symfony#27591 [VarDumper] Fix dumping ArrayObject and ArrayIterator instances (nicolas-grekas)
This PR was merged into the 2.8 branch. Discussion ---------- [VarDumper] Fix dumping ArrayObject and ArrayIterator instances | Q | A | ------------- | --- | Branch? | 2.8 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Properties added on child classes of `ArrayObject` and `ArrayIterator`, or dynamic properties added on instances of them were now properly dumped. This fixes it. ![image](https://user-images.githubusercontent.com/243674/41349429-2660cbc6-6f10-11e8-8015-a3d6ad8b0c9c.png) Commits ------- 3ecabfc [VarDumper] Fix dumping ArrayObject and ArrayIterator instances
2 parents 2643ec8 + 3ecabfc commit 2627c16

File tree

3 files changed

+77
-24
lines changed

3 files changed

+77
-24
lines changed

src/Symfony/Component/VarDumper/Caster/SplCaster.php

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,12 @@ class SplCaster
2929

3030
public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, $isNested)
3131
{
32-
$prefix = Caster::PREFIX_VIRTUAL;
33-
$class = $stub->class;
34-
$flags = $c->getFlags();
35-
36-
$b = array(
37-
$prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
38-
$prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),
39-
$prefix.'iteratorClass' => $c->getIteratorClass(),
40-
$prefix.'storage' => $c->getArrayCopy(),
41-
);
42-
43-
if ('ArrayObject' === $class) {
44-
$a = $b;
45-
} else {
46-
if (!($flags & \ArrayObject::STD_PROP_LIST)) {
47-
$c->setFlags(\ArrayObject::STD_PROP_LIST);
48-
$a = Caster::castObject($c, new \ReflectionClass($class));
49-
$c->setFlags($flags);
50-
}
51-
52-
$a += $b;
53-
}
32+
return self::castSplArray($c, $a, $stub, $isNested);
33+
}
5434

55-
return $a;
35+
public static function castArrayIterator(\ArrayIterator $c, array $a, Stub $stub, $isNested)
36+
{
37+
return self::castSplArray($c, $a, $stub, $isNested);
5638
}
5739

5840
public static function castHeap(\Iterator $c, array $a, Stub $stub, $isNested)
@@ -182,7 +164,7 @@ public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $s
182164

183165
$clone = clone $c;
184166
foreach ($clone as $obj) {
185-
$storage[spl_object_hash($obj)] = array(
167+
$storage[] = array(
186168
'object' => $obj,
187169
'info' => $clone->getInfo(),
188170
);
@@ -201,4 +183,27 @@ public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub
201183

202184
return $a;
203185
}
186+
187+
private static function castSplArray($c, array $a, Stub $stub, $isNested)
188+
{
189+
$prefix = Caster::PREFIX_VIRTUAL;
190+
$class = $stub->class;
191+
$flags = $c->getFlags();
192+
193+
if (!($flags & \ArrayObject::STD_PROP_LIST)) {
194+
$c->setFlags(\ArrayObject::STD_PROP_LIST);
195+
$a = Caster::castObject($c, new \ReflectionClass($class));
196+
$c->setFlags($flags);
197+
}
198+
$a += array(
199+
$prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
200+
$prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),
201+
);
202+
if ($c instanceof \ArrayObject) {
203+
$a[$prefix.'iteratorClass'] = $c->getIteratorClass();
204+
}
205+
$a[$prefix.'storage'] = $c->getArrayCopy();
206+
207+
return $a;
208+
}
204209
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ abstract class AbstractCloner implements ClonerInterface
8989
'AMQPEnvelope' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castEnvelope',
9090

9191
'ArrayObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castArrayObject',
92+
'ArrayIterator' => 'Symfony\Component\VarDumper\Caster\SplCaster::castArrayIterator',
9293
'SplDoublyLinkedList' => 'Symfony\Component\VarDumper\Caster\SplCaster::castDoublyLinkedList',
9394
'SplFileInfo' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFileInfo',
9495
'SplFileObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFileObject',

src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,51 @@ public function testCastObjectStorageDumpsInfo()
160160

161161
$this->assertDumpMatchesFormat('%ADateTime%A', $var);
162162
}
163+
164+
public function testCastArrayObject()
165+
{
166+
if (\defined('HHVM_VERSION')) {
167+
$this->markTestSkipped('HHVM as different internal details.');
168+
}
169+
$var = new \ArrayObject(array(123));
170+
$var->foo = 234;
171+
172+
$expected = <<<EOTXT
173+
ArrayObject {
174+
+"foo": 234
175+
flag::STD_PROP_LIST: false
176+
flag::ARRAY_AS_PROPS: false
177+
iteratorClass: "ArrayIterator"
178+
storage: array:1 [
179+
0 => 123
180+
]
181+
}
182+
EOTXT;
183+
$this->assertDumpEquals($expected, $var);
184+
}
185+
186+
public function testArrayIterator()
187+
{
188+
if (\defined('HHVM_VERSION')) {
189+
$this->markTestSkipped('HHVM as different internal details.');
190+
}
191+
$var = new MyArrayIterator(array(234));
192+
193+
$expected = <<<EOTXT
194+
Symfony\Component\VarDumper\Tests\Caster\MyArrayIterator {
195+
-foo: 123
196+
flag::STD_PROP_LIST: false
197+
flag::ARRAY_AS_PROPS: false
198+
storage: array:1 [
199+
0 => 234
200+
]
201+
}
202+
EOTXT;
203+
$this->assertDumpEquals($expected, $var);
204+
}
205+
}
206+
207+
class MyArrayIterator extends \ArrayIterator
208+
{
209+
private $foo = 123;
163210
}

0 commit comments

Comments
 (0)