schmittjoh / serializer

Library for (de-)serializing data of any complexity (supports JSON, and XML)
http://jmsyst.com/libs/serializer
MIT License
2.31k stars 591 forks source link

Serialization of Symfony\Component\Mime\Address #1508

Closed netbrothers-tr closed 11 months ago

netbrothers-tr commented 11 months ago
Q A
Bug report? no
Feature request? no
BC Break report? no
RFC? no

Simple serialization of objects of the given type fails. I am curious, what I might have overlooked. It might also be a bug.

Steps required to reproduce the problem

Set up a project with Serializer and Symfony Mime.

composer require jms/serializer symfony/mime egulias/email-validator

Create a simple serialization case.

<?php

declare(strict_types=1);

use JMS\Serializer\SerializerBuilder;
use Symfony\Component\Mime\Address;

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

$address = new Address('mail@acme.com', 'ACME Mail');

// Works if $address->toString() has been called before.
// Throws an exception otherwise.
echo SerializerBuilder::create()->build()->serialize($address, 'json');

// works always
echo $address->toString();

// works always
echo serialize($address);

This could be a problem with Symfony Mime, because if you call their toString() method before the serialization, the problematic encoder in the Address class gets initialized and doesn't cause the uninitialized exception anymore.

Standard PHP serialization works without a problem.

Expected Result

I would expect the serialization to work out of the box.

Actual Result

The following exception is thrown.

PHP Fatal error:  Uncaught Error: Typed static property Symfony\Component\Mime\Address::$encoder must not be accessed before initialization in [...]/vendor/jms/serializer/src/Accessor/DefaultAccessorStrategy.php:84
scyzoryck commented 11 months ago

Hi!

JMS Serialiser currently supports not static uninitialised properties, but static uninitialised properties are not supported yet. I guess it would be a simple change in the library, so feel free to create Pull Request with the changes. :) See: https://github.com/schmittjoh/serializer/blob/5a5a03a71a28a480189c5a0ca95893c19f1d120c/src/Accessor/DefaultAccessorStrategy.php#L99

Best, scyzoryck.

mbabker commented 11 months ago

Maybe it'd be best if a serialization handler was provided for the class. The Symfony serializer actually has a normalizer dedicated to handling objects from the symfony/mime component (https://github.com/symfony/symfony/pull/37847) instead of falling back to some default handler, and in the case of the Address class specifically, I imagine that trying to handle its internal details (the encoder and validator) during serialization is not intended.

netbrothers-tr commented 11 months ago

JMS Serialiser currently supports not static uninitialised properties, but static uninitialised properties are not supported yet. I guess it would be a simple change in the library, so feel free to create Pull Request with the changes. :)

@scyzoryck, thanks for pointing out the different handling of static vs. regular properties. However, this isn't (and probably shouldn't be?) done by simply adjusting the regular expression. I'm not sure why, but static properties are handled differently as you can see here and here and the exception occurs even before the regular expression is evaluated.

netbrothers-tr commented 11 months ago

Maybe it'd be best if a serialization handler was provided for the class.

@mbabker, I think that's generally the right approach. In my case, however, I will opt for a different (self written) class and convert that to Symfony\Component\Mime\Address when needed. Thank you nevertheless.