Serialização de objetos é um conceito que se expande em quase todas as linguagens de programação, o principal objetivo desta é transformar um objeto em uma forma binária ou mesmo em formato de texto (como XML, por exemplo) para poder transmiti-lo via rede ou armazenar seu conteúdo sem perda de dados.

Se você tem uma String “olá mundo” e deseja armazená-la no seu computador, você pode fazer isso facilmente com funções para escrever em arquivos, como o método fwrite. Se por outro lado você desejar enviar essa String via rede, também não tem mistério algum.

Agora imagine que você possui um objeto USUARIO que possui as propriedades id, nome, email e senha. Qual a maneira correta de salvar esse conteúdo para reutilizá-lo? A resposta é serializando. Serializando o objeto USUARIO você o transforma em um “pacote de bytes” e pode enviá-lo para onde desejar, e na outra ponta você irá fazer o processo inverso à serialização, a desserialização, ou seja, transformá-lo novamente em um objeto USUARIO.

Serializando e Desserializando em PHP

O método serialize() do PHP recebe como parâmetro um objeto qualquer que você deseje serializar e retorna uma String que representa um conjunto de bytes referentes ao objeto serializado.

Na Listagem 1 vamos mostrar a criação de uma Classe USUARIO e depois iremos serializá-la.

Listagem 1. Classe USUARIO que representa o objeto que será serializado

  <?php
   
  class PojoUsuario {
   
      private $cod_usuario;
      private $nome;
      private $email;
      private $senha;
      private $ativo;
      private $perfil;
   
      public function getCod_usuario() {
          return $this->cod_usuario;
      }
   
      public function setCod_usuario($cod_usuario) {
          $this->cod_usuario = $cod_usuario;
      }
   
      public function getNome() {
          return $this->nome;
      }
   
      public function setNome($nome) {
          $this->nome = $nome;
      }
   
      public function getEmail() {
          return $this->email;
      }
   
      public function setEmail($email) {
          $this->email = strtolower($email);
      }
   
      public function getSenha() {
          return $this->senha;
      }
   
      public function setSenha($senha) {
          $this->senha = strtolower(trim($senha));
      }    
      
      public function getAtivo() {
          return $this->ativo;
      }
   
      public function setAtivo($ativo) {
          $this->ativo = strtolower($ativo);
      }
      
      public function getPerfil() {
          return $this->perfil;
      }
   
      public function setPerfil($perfil) {
          $this->perfil = $perfil;
      }
   
  }
   
  ?>

Perceba nessa classe que temos Objeto dentro de Objeto. O atributo $perfil é outro objeto de uma classe chamada Perfil, demonstrando o quão poderosa uma serialização pode ser. No exemplo da Listagem 2 mostraremos a serialização do objeto instanciado a partir da classe acima.

Listagem 2. Serializando o Objeto USUARIO

  $pojoUsuario->setCod_usuario(1);
      $pojoUsuario->setNome('USER 001');
      $pojoUsuario->setEmail('user@email.com');
      $pojoUsuario->setPerfil($PerfilRoot);
      $pojoUsuario->setAtivo('s');
      $pojoUsuario->setSenha('123');
      $usuarioSerializado = serialize($pojoUsuario);

Neste ponto você consegue armazenar todos os dados do usuário em um objeto serializado, que pode ser armazenado em uma SESSION (que é o escopo de nosso artigo), mas também poder ser trafegado via rede. No Java, por exemplo, o processo de serialização de um determinado objeto já pode ser acoplado a uma classe através da palavra reservada “Serialize”, assim os objetos trafegados via rede já são automaticamente serializados pelo Java. Nosso processo aqui é mais manual, mas não deixa de ser eficiente e atender ao nosso problema.

Veremos mais a frente um caso real de como usar a serialização e a “desserialização” no PHP, vendo realmente o que ocorre por trás dos panos e entendendo a saída dos objetos após estes processos.

No processo de desserialização você precisará passar o objeto serializado para o método unserialize() e ele retornará o objeto USUARIO, o processo inverso do serialize(). Neste caso, estamos “desempacotando” nosso objeto para ser utilizado na nossa aplicação.

Aplicando serialize() em um caso real, o SESSION.

Um local onde a serialização pode ser muito útil é no uso das SESSIONS, onde precisamos com muita frequência dos dados do usuário logado e queremos evitar de ficar procurando no banco esses dados toda vez que precisarmos, então usamos o SESSION para armazenar o objeto completo.

O estudo de caso é este: O usuário loga no seu sistema e você cria um objeto USUARIO (igualmente ao código mostrado na Listagem 1) que representa o usuário logado no momento. Porém, em qualquer lugar da sua aplicação você gostaria de poder ver o nome, email, senha ou qualquer outro atributo pertencente ao objeto usuário. Você obviamente precisará guardar esse objeto no momento que ele fizer o login, e a forma de fazer isso é usando serialização.

No exemplo da Listagem 3 capturamos o usuário logado e serializamos o mesmo armazenando em uma SESSION, que poderá ser capturada em qualquer parte da sua aplicação.

Listagem 3. Serializando Objeto e armazenando em SESSION

  if (isset($_POST['entrar'])) {
      $pojoUsuario = ControllerUsuario::getInstance()
      ->VerificarLogin(strip_tags(trim($_POST['email'])), 
       strip_tags(trim($_POST['senha'])));    
      if ($pojoUsuario) {
          $_SESSION['usuario_logado'] = serialize($pojoUsuario);
          $_SESSION['dt_hora_logon'] = date('d/m/y h:i:s');
          echo "<script type='text/javascript'>
           location.href='painel_usuario/index.php';</script>";
      }
      else
          echo "<script type='text/javascript'> 
           alert('Email/Senha inválido, por favor tente novamente'); history.back(); 
           </script>";
  }

A partir de agora o usuário está logado e a qualquer momento podemos recuperar informações do usuário. Na Listagem 4 você verá um exemplo disto.

Listagem 4. Recuperando informação de objeto serializado

  <?php echo unserialize($_SESSION['usuario_logado'])->getEmail(); ?>
  

Lembre-se que as SESSIONS só funcionam enquanto o navegador do usuário estiver aberto e para que você possa utilizá-las você precisará inicializá-las antes de qualquer outro código, conforme a Listagem 5.

Listagem 5. Inicializando SESSION

  if (session_id() == "")
      session_start();

O código acima verifica se há uma sessão inicializada, caso não haja ele executa um session_start() que inicia uma sessão no navegador. Funcionam quase como cookies, a diferença é que possuem um “tempo de vida” menor, são mais utilizadas para processamentos naquele determinado acesso. Se você desejar ver como fica um objeto depois de serializado, você pode usar a função var_dump. O código da Listagem 6 mostra isso de forma clara e exata.

Listagem 6. Objeto Serializado

  var_dump(($_SESSION['usuario_logado']));
  /*Resultado
  string 'O:11:"PojoUsuario":6:{s:24:"�PojoUsuario�cod_usuario";s:1:"2";s:17:"�PojoUsuario�nome";
  s:17:"Ronaldo Lanhellas";s:18:"�PojoUsuario�email";
  s:27:"ronaldo.lanhellas@gmail.com";s:18:"�PojoUsuario�senha";
  s:32:"e10adc3949ba59abbe56e057f20f883e";
  s:18:"�PojoUsuario�ativo";s:1:"s";
  s:19:"�PojoUsuario�perfil";O:10:"PojoPerfil":2:
  {s:22:"�PojoPerfil�cod_perfil";s:2:"19";
   s:16:"�PojoPerfil�nome";s:4:"ROOT";}}' (length=397)
   
  */

Para quem conhece JSON, pode achar até familiar a forma de construção do objeto serializado. No código da Listagem 7 mostramos o mesmo objeto desserializado.

Listagem 7. Objeto Desserializado

  var_dump(unserialize($_SESSION['usuario_logado']));
  /* Resultado
  Oject(PojoUsuario)[1]
  private 'cod_usuario' => string '2' (length=1)
  private 'nome' => string 'Ronaldo Lanhellas' (length=17)
  private 'email' => string 'ronaldo.lanhellas@gmail.com' (length=27)
  private 'senha' => string 'e10adc3949ba59abbe56e057f20f883e' (length=32)
  private 'ativo' => string 's' (length=1)
  private 'perfil' => 
    object(PojoPerfil)[2]
      private 'cod_perfil' => string '19' (length=2)
      private 'nome' => string 'ROOT' (length=4)
   
  */

A serialização é um recurso um tanto quanto antigo, mas faz jus a sua importância. Se você nunca precisou utilizá-la, obviamente não verá muita importância, mas para quem já precisou sabe o quão é importante entender e saber utilizar os conceitos de serialização.