Object Serialization (serialize/unserialize)

Asked

Viewed 390 times

4

I was looking at a topic about serialize in PHP.

A very interesting function, but in view, very little used.


About the function, I would like to know:

  • An example of where would apply this function in a real scenario?
  • What is the advantage to use the serialize in relation to any variable?
  • Why do the serialization of an object?
  • Why then use two more steps (serialize/unserialize) to something that can be "treated" directly?
  • 1

    This is more rarely required if you want to persist the object (in file, memory or database) and recover later. I mean, in cases where you can’t "go right through".

  • @bfavaretto didn’t even imagine it. Very interesting. (despite as said, in rare needs)

  • 2

    Complementing and answering the last question (Why then use two more steps?). There are objects that use external resources (resources). Which may be database connection, stream, etc. These features cannot be persisted or automatically closed/opened. The fact of these two extra steps may be to close a resource (during serialize) and recreate the resource (during unserialize).

1 answer

6


I would like to know, for example, where I would apply this function in a real scenario?

Jobs

I use a lot to create Jobs, particularly an implementation of Laravel. It basically works like this: You serialize an instance of a class that will perform a specific action and save it to the database. Then you deserialize this class and call a method specific to that class through the command line.

Session

In addition, PHP natively uses serialize to save the data stored in the variable $_SESSION, and unserialize when you will recover this data.

See what the little code below does:

session_save_path('tmp_sessions');
session_start();

$_SESSION['nome'] = 'Wallace';

Above I set that sessions will be saved inside the folder tmp_sessions. After running the script, a file appears inside the folder tmp_sessions/sess_st3e3ksr5vjsj8h5rrm57u11l4, with the following content:

nome|s:7:"Wallace";

What is the advantage of using serialize in relation to any variable?

I think part of this question was answered above, but it is natural to use serialize in cases where you need to recover this data later, so that PHP could recover it in the same state as it was created.

Important remarks

Serialization aims at storing data in formats that are interpreted by PHP for a future recovery. You should keep in mind that there are some restrictions regarding data serialization.

One of them is Closure and also Classes Anonymous. Obviously these data cannot be serialized natively because they represent a temporary structure, which would make it very difficult to reconstruct these objects.

In cases where you need to implement serialization in a specific instance of an object, you may need to define how PHP will behave when you sort this object, in this case, or create the method __wakeup and __sleep or implementing the native interface Serializable, who has the methods serialize and unserialize. These methods aim to "point" to PHP what will or will not be serialized from that object.

Let us take the example of JOB I mentioned earlier.

In the case below, consider that I am wanting to create a "worker" who will send the emails to me from the command line, so I don’t have to do this by http.

At HTTP:

interface Trabalho
{
    public function trabalhar();
}   


class EmailNotificacao implements Trabalho, Serializable
{

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

    public function trabalhar()
    {

        $usuario = Usuario::find($this->id);

        Email::texto('Enviando email para o usuário', $usuario->email);
    }


    public function serialize()
    {
        return serialize(['id' => $this->id]);
    }

    public function unserialize($data)
    {
        $properties = unserialize($data);

        $this->id = $properties['id'];
    }
}



$id = 1;

BancoDeDados::inserir('trabalhos', serialize(new EmailNotificacao($id)));

In the above case, this allows me to insert the instance of a serialized class into the database, because the serialization always returns a string, which can easily be included in a column of the type TEXT.

Now, a script that is running on your cronjob and has access to the same class settings as your http application will be able to retrieve the data through deserialization.

Behold:

// no script do cronjob


$trabalho = BancoDeDados::obterPrimeiro('trabalhos');

$trabalho_instancia = unserialize($trabalho['dado_serializado']);


if ($trabalho_instancia instanceof Trabalho)
{

    $trabalho_instancia->trabalhar();
    BancoDeDados::deletar($trabalho_instancia->id);
}

See a small example of the customisation of serializable in the Ideone

Why then use two more steps (serialize/unserialize) for something that can be "treated" directly?

It is because you are thinking of the application in a single execution. In those cases, it really doesn’t make sense to serialize the data - unless it’s something very specific.

As I said, the purpose of serialization is to create a string containing a representation of a PHP data structure.

This can be very useful for you to save an object in a specific location to retrieve it later, as is done in the case of session.

If it weren’t for serialization, how could you save arrays, strings or even instances of certain objects in your application session?

Note that in the case of sessions you not only get the previously stored value, you get it in the same type. If you save a int, you’ll always have the same int on the new page call.

For you to understand better, the session works basically like this:

Create the script serialize.php and then create a file session.txt in the same empty folder.

Now add this to your script:

$file = 'session.txt';

// desserializa o conteúdo do arquivo

$_session = unserialize(file_get_contents($file));

// Se for false, é que o arquivo está vazio

if ($_session === false) {
    // então definimos que queremos que a variável seja um array
    $_session = [];
}

// mostra os dados da sessão

var_dump($_session);

$_session['nome'] = 'wallace';

if (! isset($_session['quantidade_execucao']))
{
    $_session['quantidade_execucao'] = 0;
}


// adiciona uma contagem para cada vez que o script é executado
$_session['quantidade_execucao']++;


// salvas os dados serializados no arquivo

file_put_contents($file, serialize($_session));

Basically, this is how the session works, and it would not be to keep the states of the variables, as in the example above, if there were no serialization.

But why not use JSON, which is so popular?

The JSON aims at communication between different languages or applications. The serialize PHP serves only and exclusively for PHP.

Moreover, the json_encode PHP, when it comes to objects, is a one-way street, as it is only able to determine how the data of an object (in the case of a specific class) will be serialized to JSON, but there is no option to do otherwise.

That is, the json_decode could never reconstruct an object like ArrayObject, for example. But serialize is able to handle it perfectly.

**Note: If you try to deserialize a serial that contains a nonexistent class on Sop, PHP will return an error, saying it cannot deserialize __php_incomplete_class.

It is always necessary, when working with class serialization, that it is included both where it serializes itself and where it is deserialized.

serialize does not do the magic of saving the source code of your class in it, it only stores the information needed to rebuild an instance. For this, it is necessary that the class exists!

Look at this question I asked about the subject:

  • Wallace, sorry for the ignorance, but it is a very "new" and distinct subject this business! rs... I "synthetically" understood, but "analytically", I’m not sure! . Will it "store" my object/instance in its current state? All object properties, something else? Always saved in $_SESSION? If I close the connection, I will lose?

  • Complementing the last sentence, recover it without losing the formats of the values saved, including class objects. What could be a great advantage (provided that the class is already stated previously in the following requisitions).

  • @Rbz calm down there, young man. I’m creating the answer to the same benefits, kkkkk

  • @Wallacemaxters I’m noticing this! rs But if I remember something about the context I describe, so I can better spend you where I am with my understanding! rs

  • @Rbz is there. Read mainly the last example, doing tests with it. You will notice how the session works.

  • @Wallacemaxters Now the business is serious! rs ... Now I need some time to digest! But I will see, understand, test... wait.. rs

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.