Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stdClass Serialization Does Not Use Property Naming Strategy #1499

Open
Brandon0 opened this issue Jul 14, 2023 · 3 comments
Open

stdClass Serialization Does Not Use Property Naming Strategy #1499

Brandon0 opened this issue Jul 14, 2023 · 3 comments

Comments

@Brandon0
Copy link

Q A
Bug report? no
Feature request? no
BC Break report? maybe?
RFC? no

I am upgrading an old application that was using jms/serializer 1.14.1. I have upgraded it to 3.24.0 and am seeing different behavior that wasn't reported as a BC and I'm not finding any information about how to get back to the old ways.

The issue revolves around serializing \stdClass objects. Previous behavior would be to apply the property naming strategy, which by default meant converting camel case to snake case. On the newer version, however, \stdClass does not appear to use the property naming strategy, even if defined explicitly.

What am I missing?

Steps required to reproduce the problem

        $data = (object) [
            "success" => true,
            "financingPartnerName" => "MoneyMan",
            "dealerFee" => 6.5,
        ];
        $serializer = \JMS\Serializer\SerializerBuilder::create()
            ->setPropertyNamingStrategy(new \JMS\Serializer\Naming\CamelCaseNamingStrategy())
            ->addDefaultHandlers()
            ->build();
        $json = $serializer->serialize($data, 'json');
        dump($json);

Expected Result

{
    "success": true,
    "financing_partner_name": "MoneyMan",
    "dealer_fee": 6.5
}

Actual Result

{
    "success": true,
    "financingPartnerName": "MoneyMan",
    "dealerFee": 6.5
}
@scyzoryck
Copy link
Collaborator

Hi!
It looks like this feature has been abandoned long time ago.
I would suggest to create a StdClass handler that will do the job for you and register it additionally. Here is the code from the standard handler that you can reuse src/Handler/StdClassHandler.php :

    public function serializeStdClass(SerializationVisitorInterface $visitor, \stdClass $stdClass, array $type, SerializationContext $context)
    {
        $classMetadata = $context->getMetadataFactory()->getMetadataForClass('stdClass');
        $visitor->startVisitingObject($classMetadata, $stdClass, ['name' => 'stdClass']);

        foreach ((array) $stdClass as $name => $value) {
            // use naming strategy for $name here.
            $metadata = new StaticPropertyMetadata('stdClass', $name, $value);
            $visitor->visitProperty($metadata, $value);
        }

        return $visitor->endVisitingObject($classMetadata, $stdClass, ['name' => 'stdClass']);
    }

@Brandon0
Copy link
Author

Hi, thank you for the response. I did notice in the docs that there were some known limitations of serializing \stdClass and it is "discouraged", but unfortunately my application does currently rely on it in some spots.

I had a similar thought with the code you posted and have gone through the exercise and implementing our own version of the stdClassHander, however, I was unable to find how we could go about accessing the configured \JMS\Serializer\Naming\PropertyNamingStrategyInterface from the context of a handler. It seems like the only place where that strategy is defined is deep within the \JMS\Serializer\Builder\DriverFactoryInterface instance and doesn't seem accessible.

Any ideas? Thanks.

@scyzoryck
Copy link
Collaborator

Hi!
I do not think that configured PropertyNamingStrategyInterface object can be fetched anywhere. But if you are using also JMS Serializer Bundle, it should be available as an service in DI container.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants