8000 [Cache][VarExporter] Then using objects with readonly properties Hydrator can't recreate them from PHPFilesAdaptor cache files · Issue #45886 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
[Cache][VarExporter] Then using objects with readonly properties Hydrator can't recreate them from PHPFilesAdaptor cache files #45886
Closed
@aurimasniekis

Description

@aurimasniekis

Symfony version(s) affected

5.4, 6.0

Description

I am using Symfony Cache component to store some configurations cache.system, and it's using PhpFileAdaptor caching everything works, but after cache trying to read it fails because Hydrator is unable to fill those properties back.

I am not sure if this is allowed to use readonly properties in cached objects, but following PSR-6 standard it's allowed.

Object - Any object that supports lossless serialization and deserialization such that $o == unserialize(serialize($o)). Objects MAY leverage PHP's Serializable interface, __sleep() or __wakeup() magic methods, or similar language functionality if appropriate.

All data passed into the Implementing Library MUST be returned exactly as passed. That includes the variable type. That is, it is an error to return (string) 5 if (int) 5 was the value saved. Implementing Libraries MAY use PHP's serialize()/unserialize() functions internally but are not required to do so. Compatibility with them is simply used as a baseline for acceptable object values.

Looks like the issue is related to this Hydrator:

https://github.com/symfony/symfony/blob/6.1/src/Symfony/Component/VarExporter/Internal/Hydrator.php#L63

How to reproduce

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Symfony\Component\VarExporter\Internal\Hydrator;
use Symfony\Component\VarExporter\Internal\Registry;

class Model
{
    public function __construct(
        public readonly string $name,
        public readonly string $value,
    ) {
    }
}

$func = static function () { return Hydrator::hydrate(
    $o = [
        clone (($p = &Registry::$prototypes)['\\Model'] ?? Registry::p('Model')),
        clone $p['Model'],
    ],
    null,
    [
        'stdClass' => [
            'name' => [
                'foo',
                'bar',
            ],
            'value' => [
                'bar',
                'foo',
            ],
        ],
    ],
    [
        $o[0],
        $o[1],
    ],
    []
); };

$func();

Possible Solution

I am not sure which is the best way here, but I think using some of Property component to allow reconstruct objects, or last chance to use mentioned serialize/unserialize methods.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0