Skip to content

Commit 6be65eb

Browse files
kerbert101greg0ire
authored andcommitted
fix: return property names in AbstractSqlExecutor::__sleep
Property names as returned by a cast to array are mangled, and that mangling is not documented. Returning unprefixed produces the same result, and is more likely to be supported by external tools relying on the documented possible return values of __sleep. For instance symfony/var-exporter does not support mangled names, which leads to issues when caching query parsing results in Symfony applications.
1 parent e8afa9f commit 6be65eb

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

Diff for: lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
use function array_diff;
1313
use function array_keys;
14+
use function array_map;
1415
use function array_values;
16+
use function str_replace;
1517

1618
/**
1719
* Base class for SQL statement executors.
@@ -84,7 +86,9 @@ public function __sleep(): array
8486
serialized representation becomes compatible with 3.0.x, meaning
8587
there will not be a deprecation warning about a missing property
8688
when unserializing data */
87-
return array_values(array_diff(array_keys((array) $this), ["\0*\0_sqlStatements"]));
89+
return array_values(array_diff(array_map(static function (string $prop): string {
90+
return str_replace("\0*\0", '', $prop);
91+
}, array_keys((array) $this)), ['_sqlStatements']));
8892
}
8993

9094
public function __wakeup(): void

Diff for: tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php

+31-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Doctrine\Tests\ORM\Functional;
66

7+
use Closure;
78
use Doctrine\ORM\Query;
89
use Doctrine\ORM\Query\Exec\SingleSelectExecutor;
910
use Doctrine\ORM\Query\ParserResult;
@@ -12,6 +13,8 @@
1213
use Generator;
1314
use ReflectionMethod;
1415
use ReflectionProperty;
16+
use Symfony\Component\VarExporter\Instantiator;
17+
use Symfony\Component\VarExporter\VarExporter;
1518

1619
use function file_get_contents;
1720
use function rtrim;
@@ -27,21 +30,46 @@ protected function setUp(): void
2730
parent::setUp();
2831
}
2932

30-
public function testSerializeParserResult(): void
33+
/**
34+
* @param Closure(ParserResult): ParserResult $toSerializedAndBack
35+
*
36+
* @dataProvider provideToSerializedAndBack
37+
*/
38+
public function testSerializeParserResult(Closure $toSerializedAndBack): void
3139
{
3240
$query = $this->_em
3341
->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u.name = :name');
3442

3543
$parserResult = self::parseQuery($query);
36-
$serialized = serialize($parserResult);
37-
$unserialized = unserialize($serialized);
44+
$unserialized = $toSerializedAndBack($parserResult);
3845

3946
$this->assertInstanceOf(ParserResult::class, $unserialized);
4047
$this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping());
4148
$this->assertEquals(['name' => [0]], $unserialized->getParameterMappings());
4249
$this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor());
4350
}
4451

52+
/** @return Generator<string, array{Closure(ParserResult): ParserResult}> */
53+
public function provideToSerializedAndBack(): Generator
54+
{
55+
yield 'native serialization function' => [
56+
static function (ParserResult $parserResult): ParserResult {
57+
return unserialize(serialize($parserResult));
58+
},
59+
];
60+
61+
$instantiatorMethod = new ReflectionMethod(Instantiator::class, 'instantiate');
62+
if ($instantiatorMethod->getReturnType() === null) {
63+
$this->markTestSkipped('symfony/var-exporter 5.4+ is required.');
64+
}
65+
66+
yield 'symfony/var-exporter' => [
67+
static function (ParserResult $parserResult): ParserResult {
68+
return eval('return ' . VarExporter::export($parserResult) . ';');
69+
},
70+
];
71+
}
72+
4573
public function testItSerializesParserResultWithAForwardCompatibleFormat(): void
4674
{
4775
$query = $this->_em

0 commit comments

Comments
 (0)