Skip to content

Commit 5691cd2

Browse files
committed
Dumper: supports __serialize()
1 parent 8831a3e commit 5691cd2

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/PhpGenerator/Dumper.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,12 @@ private function dumpArray(array &$var, array $parents, int $level, int $column)
138138
/** @param array<mixed[]|object> $parents */
139139
private function dumpObject(object $var, array $parents, int $level): string
140140
{
141-
if ($var instanceof \Serializable) {
141+
$class = $var::class;
142+
if (method_exists($var, '__serialize')) {
143+
$data = $this->dump($var->__serialize());
144+
return '\\' . self::class . "::createObject(\\$class::class, $data)";
145+
146+
} elseif ($var instanceof \Serializable) { // deprecated
142147
return 'unserialize(' . $this->dumpString(serialize($var)) . ')';
143148

144149
} elseif ($var instanceof \UnitEnum) {
@@ -155,7 +160,6 @@ private function dumpObject(object $var, array $parents, int $level): string
155160
throw new Nette\InvalidArgumentException('Cannot dump closure.');
156161
}
157162

158-
$class = $var::class;
159163
if ((new \ReflectionObject($var))->isAnonymous()) {
160164
throw new Nette\InvalidArgumentException('Cannot dump anonymous class.');
161165

@@ -270,6 +274,11 @@ private function dumpArguments(array &$var, int $column, bool $named): string
270274
*/
271275
public static function createObject(string $class, array $props): object
272276
{
277+
if (method_exists($class, '__serialize')) {
278+
$obj = (new \ReflectionClass($class))->newInstanceWithoutConstructor();
279+
$obj->__unserialize($props);
280+
return $obj;
281+
}
273282
return unserialize('O' . substr(serialize($class), 1, -1) . substr(serialize($props), 1));
274283
}
275284
}

tests/PhpGenerator/Dumper.dump().phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,26 @@ if (PHP_VERSION_ID < 80100) {
172172
}
173173

174174

175+
// __serialize
176+
class TestSer
177+
{
178+
public function __serialize(): array
179+
{
180+
return ['a', 'b'];
181+
}
182+
183+
184+
public function __unserialize(array $data): void
185+
{
186+
}
187+
}
188+
189+
190+
$dumper = new Dumper;
191+
Assert::same('\Nette\PhpGenerator\Dumper::createObject(\TestSer::class, [\'a\', \'b\'])', $dumper->dump(new TestSer));
192+
Assert::equal(new TestSer, eval('return ' . $dumper->dump(new TestSer) . ';'));
193+
194+
175195

176196
// datetime
177197
class TestDateTime extends DateTime

0 commit comments

Comments
 (0)