O que é Serialização de dados?

Basicamente é o processo de salvar dados de um objeto, mas não obrigatoriamente um objeto, em algum lugar ou transmiti-lo pela rede, num formato binário eu de texto. Sendo que esses bytes poderão ser utilizados para reconstruir perfeitamente o que foi serializado.

Um exemplo muito claro disso, que muitos usam, pois é muito bom, é que quando você está jogando um joginho e precisa fazer uma parada, mas não quer perder o estado do jogo, o que você faz? Salva (“serializa”) em algum lugar para depois carregar (“deserializa”) o jogo e tudo volta de onde parou.

Serializando no PHP

Primeiro quero dizer que a Serialização não é coisa nova não e muito menos exclusivo do PHP.

No PHP ela é feita de forma extremamente simples, usamos o método serialize() que recebe o que deve ser serializado. Vejam:

Listagem 01: Serializando


<?php
$array = array( "a","b","c","d","e" );
$serializado = serialize($array);
echo $serializado;
//resultado a:5:{i:0;s:1:"a";i:1;s:1:"b";i:2;s:1:"c";i:3;s:1:"d";i:4;s:1:"e";}
?>

Lembrando que não podemos serializar recursos, ou seja, arquivos, conexão como banco de dados, etc. E que tudo que você coloca numa variável de sessão é serializado automaticamente.

Restaurando os Dados

Para restaurar os dados serializados usamos a função unserialize() que recebe o dado serializado, interpreta a string e traz de volta o que foi serializado. Vejam como ficaria para o exemplo da Listagem 01:

Listagem 02: Restaurando os dados


<?php
$serialziado = 'a:5:{i:0;s:1:"a";i:1;s:1:"b";i:2;s:1:"c";i:3;s:1:"d";i:4;s:1:"e";}';
$array = unserialize($serialziado);
var_dump($array);
/*
array(5) { 
	[0]=> string(1) "a" 
	[1]=> string(1) "b" 
	[2]=> string(1) "c" 
	[3]=> string(1) "d" 
	[4]=> string(1) "e" 
	}
*/
?>

Caso a string passada não seja uma string serializada o método retornará falsee um E_NOTICE.

Serialização de objetos

Bem, nós já serializamos e restauramos um array e com objetos o processo é exatamente o mesmo porem pode fazer uso de dois métodos muito úteis, __sleep() e __wakeup().

  • __sleep(): é invocado quando um objeto é serializado, ou seja, no momento da execução de serialize(), usamos ele para informar quais dados devem ser serializados, para isso devemos retornar um array com o nome dos campos que devem ser serializados. Lembrando que ele será executado tanto quando usamos serialize() diretamente ou quando enviamos uma variável para a sessão.
  • __wakeup(): faz o contrario de __sleep(), ele é invocado quando estamos restaurando um objeto por meio de unserialize() ou quando chamamos uma variável de sessão. Usamos para setar valores padrões para quando restauramos os dados.

Vejamos na Listagem 03 o uso desses dois métodos construindo uma classe Jogador.

Listagem 03: Implementando __sleep() e __wakeup()


<?php
//arquivo jogador.php
class Jogador {	
	private $nome;
	private $hp;
	private $score;	
	public function __construct($nome){
		$this->nome = $nome;
		$this->hp   = 100;
		$this->score = 0; 
	}	
	/* get's e set's aqui */	
	public function __sleep(){		
		return array(		
			"nome","score"		
		);		
	}	
	public function __wakeup(){		
		$this->hp = 100;		
	}	
}
?> 

Dissemos aqui ao PHP para serializar apenas o nome e o score do jogador e que quando restaurarmos o hp deve ser igual a 100.

Salvando e Lendo de arquivos

Uma forma de persistir os dados serializados é salvar em um arquivo para isso podemos usar file_put_contents() que recebe o nome do arquivo e o conteúdo e então a partir de um arquivo gravado podemos lê-lo, com file_get_contents(), e restaurar os dados. Vamos aproveitar a classe criada na Listagem 03 para demonstrar a persistência e leitura em arquivo na Listagem 04.

Listagem 04: Salvando e lendo dados em arquivo


<?php
//serializaFile.php
include_once 'jogador.php';
$jogador = new Jogador("Allan");
$jogador->setHp(1);
$jogador->setScore(1500);
$serializado = serialize($jogador);
file_put_contents("jogo.save",$serializado);
echo ("jogo salvo!");
?>
<?php
//restauraFile.php
include 'jogador.php';
$dados = file_get_contents("jogo.save");
$jogador = unserialize($dados);
echo " nome ".$jogador->getNome()." score ".$jogador->getScore()." hp ".$jogador->getHp();
?> 

O que é feito aqui é muito simples, em serializaFile.php criamos um novo jogador e setamos alguns valores para ele e salvamos no arquivo jogo.save enquanto em restauraFile.php realizamos a leitura do arquivo e restauramos o objeto serializado.

Bem pessoal fico por aqui espero que tenham gostado, cometem, compartilhem e até a próxima.