2

I have a PHP plain array which I need converted to it's original entity. Example:

class Contact
{
    protected $name;
    getName(){}
    setName(){}
}

This gets send back and forth via an API, and at some point I have that contact as an array element:

$example = ['name'=>'Foo Bar'];

I would like that back as an Contact class. At the moment, I can do that via a serialize/deserialize, but I'm hoping there is a more efficient method for this:

foreach($examples as $example) {
    $temp    = $this->serializer->serialize($example, 'json');
    $contact = $this->serializer->deserialize($temp, Contact::class, 'json');
}

This works, and $contact is now instance of Contact. But I have to perform this on 100 items in one go, possibly more.

I'm thinking of creating a toObject() method, which assigns the values by keys, but that doesn't seem a lot better.

Is there way to accomplish this without writing my own logic or doing the extra serializing step?

Please note: I get the data array, I cant get the 'raw' json. Please take that 'as is'.

2
  • 1
    Where exactly is the array coming from? You said the data was transferred over an api which implies it is already serialized. In any event, I get array data from database queries and then typically use a fromArray sort of method to populate entities. Commented Sep 12, 2019 at 13:46
  • There are more parameters send, like and ID for an order and a hash for security. That all is json_decoded, so I have it as array. Doesnt really matter how it got there, that's what I've got to work with :) Commented Sep 12, 2019 at 13:54

1 Answer 1

1

Denormalizing from raw JSON input

If you are getting the information from an API, you could probably do away with the JSON conversion and deal with the input directly, since most likely the API is not sending you a native array, but a JSON you are converting to an array at some point

The Serializer component can handle arrays as well, directly.

Assuming an input JSON like this:

$data = '[
   {
     "name": "Mary"
   },
   {
     "name": "Jane",
   },
   {
     "name": "Alice"
   }
]';

You could call deserialize() saying you expect Contact[] in your input data:

$contacts = $serializer->deserialize($data, Contact::class . '[]', 'json');

This would get you a Contact array in one single step.


Denormalizing from array to object

If for some reason the original input is not available or not readily unserializable and you really need to convert from an array to an object one by one, and your objects have setters like the ones you show in your question; you could simply use the GetSetMethodNormalizer (one of the normalizers than the Serializer component uses internally).

E.g.:

$contacts = [
  ['name' => 'Mary'],
  ['name' => 'Jane'],
  ['name' => 'Alice'],
];

$normalizer = new GetSetMethodNormalizer();
foreach($contacts as $arrayContact){
    $contact = $normalizer->denormalize(Contact::class, $arrayContact);
    // do something with $contact;
}
Sign up to request clarification or add additional context in comments.

3 Comments

This fixed my issue, I recommend to edit your answer so the bulk solution is first
Ok, thanks, I'll do that. I had put it this way because it seemed to address your question more directly, but I do believe doing it directly with serializer and the raw input it's a better way to go; and if you agree I'll just reverse the answer blocks.
I simply wasnt aware that you could do a complete array in one go, so I never though about that :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.