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

Excluding an item in an array results in a Json object instead of an array #1300

Closed
arneee opened this issue Mar 20, 2021 · 1 comment
Closed

Comments

@arneee
Copy link
Contributor

arneee commented Mar 20, 2021

Q A
Bug report? yes
Feature request? no

Assume the following code:

class MyItem {
    public string $color;

    public function __construct($color) {
        $this->color = $color;
    }
}

$items = [new MyItem("red"), new MyItem("green"), new MyItem("blue")];

$string = $serializer->serialize($items,'json');

echo $string;

The result is a javascript object with the three items:

[ { "color": "red" }, { "color": "green" }, { "color": "blue" } ]

Now add an ExcludeIf to the MyItem class:

/**
 * @JMS\Exclude(if="object.color == 'green'")
 */
class MyItem {
    public string $color;

    public function __construct($color) {
        $this->color = $color;
    }
}

The result is now a javascript object:

{ "0": { "color": "red" }, "2": { "color": "blue" } }

This is an issue if you use the result in javascript, since there is for example no forEach() anymore on an object type.

The issue seems to be, that in visitArray of JsonSerializationVisitor the result array is constructed including the keys. While this is important for associate arrays, in our case it leads to a "missing" key in the array, which leads to json_encode returning an object.

A workaround is to explicitly provide the $type to serialize(), but it would be nice to have that behaviour automatically.

$string = $this->serializer->serialize($items,'json',null,'array<MyItem>');

Unfortunately it seems like there is no easy way to know if the provided array is a "regular" array or an associate array, since all arrays in PHP are associative arrays. .

What do you think?

@goetas
Copy link
Collaborator

goetas commented Mar 21, 2021

adding array<MyItem> is what needs to be done. any other way will lead to issues. what f i want to have it an object and not an array?

The current serializer behavior is consistent:

  • $this->serializer->serialize($items,'json',null,'array<MyItem>'); is always serialized as [...]
  • $this->serializer->serialize($items,'json',null,'array<string,MyItem>'); is always serialized as {...}
  • $this->serializer->serialize($items,'json'); is serialized in an inconsistent way and can be [...] or {...} depending on the internal structure of $items

This feature has been introduced with #728 (that fixed many other situations in which was not clear how arrays should be serialized)

@goetas goetas closed this as completed Mar 21, 2021
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