serializer
serializer copied to clipboard
stdClass Serialization Does Not Use Property Naming Strategy
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
}
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']);
}
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.
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.