-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Closed
Description
Symfony version(s) affected
6.3.x
Description
I'm using ext-ds especially Ds\Map quite often mainly because the Ds\Map allows objects as keys.
Unfortunately this breaks the VarDumper in my case triggered by the profiler:
php.CRITICAL: Uncaught Error: Symfony\Component\VarDumper\Caster\DsPairStub::__construct(): Argument #1 ($key) must be of type string|int, App\Entity\GeoCountry given, called in /app/vendor/symfony/var-dumper/Caster/DsCaster.php on line 43 {"exception":"[object] (TypeError(code: 0): Symfony\\Component\\VarDumper\\Caster\\DsPairStub::__construct(): Argument #1 ($key) must be of type string|int, App\\Entity\\\GeoCountry given, called in /app/vendor/symfony/var-dumper/Caster/DsCaster.php on line 43 at /app/vendor/symfony/var-dumper/Caster/DsPairStub.php:21)
[stacktrace]
#0 /app/vendor/symfony/var-dumper/Caster/DsCaster.php(43): Symfony\\Component\\VarDumper\\Caster\\DsPairStub->__construct(Object(App\\Entity\\\GeoCountry), Array)
#1 /app/vendor/symfony/var-dumper/Cloner/AbstractCloner.php(363): Symfony\\Component\\VarDumper\\Caster\\DsCaster::castMap(Object(Ds\\Map), Array, Object(Symfony\\Component\\VarDumper\\Cloner\\Stub), true, 0)
#2 /app/vendor/symfony/var-dumper/Cloner/VarCloner.php(130): Symfony\\Component\\VarDumper\\Cloner\\AbstractCloner->castObject(Object(Symfony\\Component\\VarDumper\\Cloner\\Stub), true)
#3 /app/vendor/symfony/var-dumper/Cloner/AbstractCloner.php(302): Symfony\\Component\\VarDumper\\Cloner\\VarCloner->doClone(Array)
#4 /app/vendor/symfony/http-kernel/DataCollector/DataCollector.php(55): Symfony\\Component\\VarDumper\\Cloner\\AbstractCloner->cloneVar(Array)
#5 /app/vendor/symfony/messenger/DataCollector/MessengerDataCollector.php(47): Symfony\\Component\\HttpKernel\\DataCollector\\DataCollector->cloneVar(Array)
#6 /app/vendor/symfony/http-kernel/Profiler/Profiler.php(100): Symfony\\Component\\Messenger\\DataCollector\\MessengerDataCollector->lateCollect()
#7 /app/vendor/symfony/http-kernel/EventListener/ProfilerListener.php(135): Symfony\\Component\\HttpKernel\\Profiler\\Profiler->saveProfile(Object(Symfony\\Component\\HttpKernel\\Profiler\\Profile))
#8 /app/vendor/symfony/event-dispatcher/Debug/WrappedListener.php(116): Symfony\\Component\\HttpKernel\\EventListener\\ProfilerListener->onKernelTerminate(Object(Symfony\\Component\\HttpKernel\\Event\\TerminateEvent), '...', Object(Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher))
#9 /app/vendor/symfony/event-dispatcher/EventDispatcher.php(220): Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener->__invoke(Object(Symfony\\Component\\HttpKernel\\Event\\TerminateEvent), '...', Object(Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher))
#10 /app/vendor/symfony/event-dispatcher/EventDispatcher.php(56): Symfony\\Component\\EventDispatcher\\EventDispatcher->callListeners(Array, '...', Object(Symfony\\Component\\HttpKernel\\Event\\TerminateEvent))
#11 /app/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php(139): Symfony\\Component\\EventDispatcher\\EventDispatcher->dispatch(Object(Symfony\\Component\\HttpKernel\\Event\\TerminateEvent), '...')
#12 /app/vendor/symfony/http-kernel/HttpKernel.php(115): Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher->dispatch(Object(Symfony\\Component\\HttpKernel\\Event\\TerminateEvent), '...')
#13 /app/vendor/symfony/http-kernel/Kernel.php(157): Symfony\\Component\\HttpKernel\\HttpKernel->terminate(Object(Symfony\\Component\\HttpFoundation\\Request), Object(Symfony\\Component\\HttpFoundation\\Response))
#14 /app/vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php(39): Symfony\\Component\\HttpKernel\\Kernel->terminate(Object(Symfony\\Component\\HttpFoundation\\Request), Object(Symfony\\Component\\HttpFoundation\\Response))
#15 /app/vendor/autoload_runtime.php(29): Symfony\\Component\\Runtime\\Runner\\Symfony\\HttpKernelRunner->run()
#16 /app/public/index.php(7): require_once('...')
#17 {main}
The problem happens in DsCaster::castMap:
public static function castMap(Map $c, array $a, Stub $stub, bool $isNested): array
{
foreach ($c as $k => $v) {
$a[] = new DsPairStub($k, $v);
}
return $a;
}... where DsPairStub accepts only int|string:
public function __construct(string|int $key, mixed $value)
{
$this->value = [
Caster::PREFIX_VIRTUAL.'key' => $key,
Caster::PREFIX_VIRTUAL.'value' => $value,
];
}How to reproduce
Create a Ds\Map, put an object as key and pass it to VarDumper.
Possible Solution
Allow mixed for the $key on DsPairStub::construct - this solves the problem for me but I'm not sure what other implications this might have.
Additional Context
Keys of type object are supported. If an object implements Ds\Hashable, equality will be determined by the object's equals function. If an object does not implement Ds\Hashable, objects must be references to the same instance to be considered equal.