Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Serializer] Support for array denormalization #14756

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

Merged
merged 1 commit into from
May 27, 2015

Conversation

derrabus
Copy link
Member

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets none
License MIT
Doc PR symfony/symfony-docs#5360

This is a rebase of #14343 against the 2.8 branch.

I had to implement a couple of API endpoints that receive data as JSON-serialized arrays of objects. The current implementation of the Serializer component is capable of serializing such arrays, but so far this operation is a one-way-road. This PR is an attempt to change this.

Demo

class Dummy
{
    public $foo;
    public $bar;

    public function __construct($foo = null, $bar = null)
    {
        $this->foo = $foo;
        $this->bar = $bar;
    }
}

$serializer = new \Symfony\Component\Serializer\Serializer(
    array(
        new \Symfony\Component\Serializer\Normalizer\PropertyNormalizer(),
        new \Symfony\Component\Serializer\Normalizer\ArrayDenormalizer()
    ),
    array(
        new \Symfony\Component\Serializer\Encoder\JsonEncoder()
    )
);

$json = $serializer->serialize(
    array(
        new Dummy('one', 'two'),
        new Dummy('three', 'four')
    ),
    'json'
);

echo $json . "\n\n";

// Deserialize the JSON string, so we get back to where we started from.
$data = $serializer->deserialize($json, 'Dummy[]', 'json');

var_dump($data);

By appending [] to the type parameter, you indicate that you expect to deserialize an array of objects of the given type. This is the same notation that phpDocumentor uses to indicate collections. The denormalization of the array is implemented recursively: The denormalizer simply calls Serializer::denormalize() on each element of the array. This way, the ArrayDenormalizer can be combined with any other denormalizer.

Side effects

For this implementation, I had to touch GetSetMethodNormalizer, PropertyNormalizer and CustomNormalizer. Those classes expected supportsDenormalization to be called with a valid class in the $type parameter. Instead of throwing a reflection exception, they now simply return false. I'm not exactly sure, if this is should be considered to be a BC break.

This implementation violates the SerializerInterface which declared deserialize() to always return an object. But imho, the assumption that serialized data always represents an object is too restrictive anyway. Also, this declaration is not consistent with the serialize() method which accepts mixed as input type for the data to serialize.

Other PRs

I've found an older PR adressing this issue, #12066. That PR was closed because the contributor did not reply to feedback.

@dunglas
Copy link
Member

dunglas commented May 26, 2015

👍 once fabbot is happy.

@derrabus
Copy link
Member Author

fabbot complains about lines I haven't touched. Not sure if I should fix them with my PR.

@derrabus
Copy link
Member Author

See #14758 for the fabbot complaints. Those CS issues are already present in 2.6.

@dunglas
Copy link
Member

dunglas commented May 27, 2015

Thank you @derrabus.

@dunglas dunglas merged commit 0573f28 into symfony:2.8 May 27, 2015
dunglas added a commit that referenced this pull request May 27, 2015
This PR was merged into the 2.8 branch.

Discussion
----------

[Serializer] Support for array denormalization

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | none
| License       | MIT
| Doc PR        | none (yet)

This is a rebase of #14343 against the 2.8 branch.

I had to implement a couple of API endpoints that receive data as JSON-serialized arrays of objects. The current implementation of the Serializer component is capable of serializing such arrays, but so far this operation is a one-way-road. This PR is an attempt to change this.

## Demo
```php
class Dummy
{
    public $foo;
    public $bar;

    public function __construct($foo = null, $bar = null)
    {
        $this->foo = $foo;
        $this->bar = $bar;
    }
}

$serializer = new \Symfony\Component\Serializer\Serializer(
    array(
        new \Symfony\Component\Serializer\Normalizer\PropertyNormalizer(),
        new \Symfony\Component\Serializer\Normalizer\ArrayDenormalizer()
    ),
    array(
        new \Symfony\Component\Serializer\Encoder\JsonEncoder()
    )
);

$json = $serializer->serialize(
    array(
        new Dummy('one', 'two'),
        new Dummy('three', 'four')
    ),
    'json'
);

echo $json . "\n\n";

// Deserialize the JSON string, so we get back to where we started from.
$data = $serializer->deserialize($json, 'Dummy[]', 'json');

var_dump($data);
```

By appending `[]` to the type parameter, you indicate that you expect to deserialize an array of objects of the given type. This is the same notation that phpDocumentor uses to indicate collections. The denormalization of the array is implemented recursively: The denormalizer simply calls `Serializer::denormalize()` on each element of the array. This way, the ArrayDenormalizer can be combined with any other denormalizer.

## Side effects

For this implementation, I had to touch `GetSetMethodNormalizer`, `PropertyNormalizer` and `CustomNormalizer`. Those classes expected `supportsDenormalization` to be called with a valid class in the `$type` parameter. Instead of throwing a reflection exception, they now simply return false. I'm not exactly sure, if this is should be considered to be a BC break.

This implementation violates the `SerializerInterface` which declared `deserialize()` to always return an object. But imho, the assumption that serialized data always represents an object is too restrictive anyway. Also, this declaration is not consistent with the `serialize()` method which accepts `mixed` as input type for the data to serialize.

## Other PRs

I've found an older PR adressing this issue, #12066. That PR was closed because the contributor did not reply to feedback.

Commits
-------

0573f28 Support for array denormalization.
@derrabus derrabus deleted the 2.8-array-denormalization branch May 27, 2015 15:57
fabpot added a commit that referenced this pull request May 27, 2015
This PR was merged into the 2.6 branch.

Discussion
----------

[Serializer] [2.6] Code style

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | none
| License       | MIT
| Doc PR        | none

This PR fixes some minor code style issues fabbot discovered while I was working on PR #14756.

Commits
-------

864136a Code style
@SoboLAN
Copy link

SoboLAN commented May 31, 2015

@dunglas This will be available only in 2.8 ?

@dunglas
Copy link
Member

dunglas commented May 31, 2015

Yes as it's a new feature.

xabbuh added a commit to symfony/symfony-docs that referenced this pull request Jun 28, 2015
This PR was squashed before being merged into the 2.8 branch (closes #5360).

Discussion
----------

[Serializer] Array Denormalization

| Q             | A
| ------------- | ---
| Doc fix?      | no
| New docs?     | yes (symfony/symfony#14756)
| Applies to    | 2.8
| Fixed tickets | none

This PR adds documentation for the new `ArrayDenormalizer` class to the serializer documentation.

Commits
-------

9718c14 [Serializer] Array Denormalization
@fabpot fabpot mentioned this pull request Nov 16, 2015
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

Successfully merging this pull request may close these issues.

3 participants