1

I'm trying to retrieve some data from a controller in a serialized format that I can unserialize later. For example, I have created an entity with the following data fields

MyEntity

  • entity_id
  • identifier
  • created_at
  • updated_at

In my controller's execution method I retrieve the list of results based on my criteria.

Now I would like to return a JSON response serialized object in this format

{result:[{'entity_id': 'id', 'identifier': 'identifier'},{...},{...}]}`

I'm trying to use the SerializerInterface to do this

serializer->serialize($item)

but serializing the entities gives empty values like this which is my first issue.

{"result":[{},{},{},{}]}

Later on, in another controller, I would have loved to do the following based on the results retrieved from the first controller which is my second issue.

unserialize($response->getBody()->getContents()->result)

And give me an array of MyEntity items

MyEntity[]

In Symfony, I can already do this using the serializer component which is very powerful and allows me to group attributes I want to expose and also ignore things I don't want to expose so I guess I'm looking for something similar. Is there a Magento 2 implementation for this?

https://symfony.com/doc/current/components/serializer.html

After further digging I noticed that the serializer for json executes a simple json_encode so there probably isn't any standard implementation for serializing/unserializing an object. The best I could do to serialize the Model was to implement in my model the \JsonSerializable interface like this

 public function jsonSerialize()
    {
        return [
          self::KEY_KEY => $this->getData(self::KEY_KEY),
          self::KEY_IDENTIFIER => $this->getData(self::KEY_IDENTIFIER),
          self::KEY_NAME => $this->getData(self::KEY_NAME),
          self::KEY_DESCRIPTION => $this->getData(self::KEY_DESCRIPTION),
        ];
    }

I would love to be able to utilize a framework method to do this though so I'm still looking for an answer to this as well as to how to decode the serialized string back to the Object's Class.

4 Answers 4

3

I highly suggest using \Magento\Framework\Serialize\Serializer\Json

5
  • Magento 2 has noted in the devdocs that this implementation should not be used directly any longer For security reasons, SerializerInterface implementations, such as the Json and Serialize classes, should not serialize and unserialize objects.
    – gabtzi
    Commented Apr 20, 2020 at 12:19
  • good point, I'd didn't know this Commented Apr 20, 2020 at 12:20
  • Yeah I know. They added it at some point along with this Magento discourages using the Serialize implementation directly because it can lead to security vulnerabilities. Always use the SerializerInterface for serializing and unserializing.
    – gabtzi
    Commented Apr 20, 2020 at 12:21
  • however "The main purpose of data serialization is to convert data into a string using serialize() to store in a database, a cache, or pass onto another layer in the application." is exactly what you want to do.... Commented Apr 20, 2020 at 12:22
  • Yes indeed, however it's still not able to handle Object serialization. If I pass the data as array it's gonna work using the interface or the implementation directly, but I would like to serialize the whole object in my case.
    – gabtzi
    Commented Apr 20, 2020 at 12:27
2
<?php

namespace Demo\Demo\Demo;

use Magento\Framework\Serialize\SerializerInterface;

class DemoClass
{
    /**
     * @var SerializerInterface
     */
    protected $serializer;

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

    public function arrayToJson($data)
    {
        return $this->serializer->serialize($data);
    }

    public function jsonToArray($data)
    {
        return $this->serializer->unserialize($data);
    }
}

I think you need something like above.

4
  • SerializerInterface is not always the jsonserializer Commented Apr 20, 2020 at 12:17
  • @PhilippSander Please explain more about it.
    – Msquare
    Commented Apr 20, 2020 at 12:18
  • So you're suggesting I create my own serializer / unserializer or add it to my models? I'm confused as this would basically serialize an array and not an object as I am trying to do.
    – gabtzi
    Commented Apr 20, 2020 at 12:22
  • use Magento\Catalog\Model\ResourceModel\Product\Collection; $this->productCollection->addFieldToFilter('status', '1')->toArray(); Something like above gives array to serialize then into JSON. Commented Apr 20, 2020 at 12:34
2

From Magento 2 documentation:

Json (default)

The Magento\Framework\Serialize\Serializer\Json class serializes and unserializes data using the JSON format.

JsonHexTag

The Magento\Framework\Serialize\Serializer\JsonHexTag class serializes and unserializes data using the JSON format using the JSON_HEX_TAG option enabled.

Base64Json

The Magento\Framework\Serialize\Serializer\Base64Json class serializes and encodes in the base64 format, and decodes the base64 encoded string and unserializes data using the JSON format.

Serialize

The Magento\Framework\Serialize\Serializer\Serialize class is less secure than the Json implementation but provides better performance on large arrays.

FormData

The Magento\Framework\Serialize\Serializer\FormData class unserializes the form data using the JSON format. This class does not serialize objects to a form data format.

Magento discourages using the Serialize implementation directly because it can lead to security vulnerabilities. Always use the SerializerInterface for serializing and unserializing.

Usage

Declare SerializerInterface as a constructor dependency to get an instance of a serializer class.

use Magento\Framework\Serialize\SerializerInterface;

...

/**
 * @var SerializerInterface
 */
private $serializer;

...

public function __construct(SerializerInterface $serializer) {
  $this->serializer = $serializer;
}
-2

Another option is writing something like this in a helper

public function decode($data)
{
    return \Zend_Json::decode($data);
}
6
  • This is a bad practice, you should use DI to import the class.
    – Nikola
    Commented Aug 10, 2021 at 20:07
  • 1
    I disagree. For this safer and less likely to be affected by the framework changing the serialization method in future due to security concerns. Meanwhile magento is extremely unlikely to decoupled from zend Commented Aug 10, 2021 at 21:48
  • 2
    Zend_Json has been removed in 2.4.6. Always rely on the framework API, not on 3rd party libraries
    – MTP
    Commented Mar 22, 2023 at 5:35
  • Quick fix : magento.stackexchange.com/a/365432 Commented Jun 7, 2023 at 20:47
  • @DominicPixie "Meanwhile magento is extremely unlikely to decoupled from zend" this aged very poorly LOL Commented May 7 at 21:20

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.