A serialização provavelmente trata da conversão de algumas variáveis em um fluxo de bytes de strings, o que facilita a transmissão e o armazenamento. Claro, não há nada a ver com transmissão e armazenamento. A chave é que ele pode ser convertido novamente em formato de string e a estrutura de dados original pode ser mantida.
Existem muitas funções de serialização em PHP: serialize(). Esta função converte qualquer valor de variável (exceto variáveis de recurso) na forma de uma string. A string pode ser salva em um arquivo, ou registrada como uma sessão, ou mesmo usar curl para. simule GET/POST para transferir variáveis para obter o efeito de RPC.
Se você deseja converter variáveis serializadas em valores de variáveis originais do PHP, você pode usar a função unserialize().
1. Serialização de variáveis
Vamos dar um exemplo simples para ilustrar a serialização e seu formato de armazenamento.
Tipo inteiro:
$var = 23;
echo serialize($var);
Saída
:
i:23;
Tipo de ponto flutuante:
$
var = 1,23;
echo
serialize($var)
;
eco serialize($var);
$var = "Eu sou uma variável";
echo serialize($var);
Saída:
s:16:"Esta é uma string";
s:8: "Eu sou uma variável";
tipo booleano:
$var = true;
eco serialize($var);
$var = falso;
echo serialize($var);
Saída:
b:1;
b:0;
A situação após a serialização dos tipos básicos acima é muito clara. O formato de armazenamento após a serialização é:
tipo de variável:
[comprimento da variável:] valor da variável;
Representa a divisão. O comprimento da variável é opcional, ou seja, está disponível no tipo string, mas não em outros tipos. Cada valor serializado termina com ";".
Por exemplo, depois que nosso número inteiro 23 é serializado, ele é: i:23, então ele não tem comprimento, apenas tipo e valor de variável, i representa número inteiro, separado por dois pontos, e o valor inteiro 23 é salvo posteriormente, incluindo ponto flutuante tipo (duplo) Tipo de byte) é o mesmo. Para Booleano, o tipo é b (booleano). Se for verdadeiro, o valor serializado será 1. Se for falso, o valor será 0.
Para valores
de string
, haverá um valor salvo adicional no meio, que salva o valor do comprimento da string, como a string "This is a string", então o valor serializado gerado é s:16:"This is a string ";s é uma string, representando o tipo. O 16 no meio é o comprimento da string. Se for chinês, cada caractere chinês será armazenado em dois caracteres. Por exemplo, a string "Eu sou uma variável", o valor serializado gerado é :s:8:"Eu sou uma variável"; tem 8 caracteres de comprimento.A seguir, nos concentraremos na serialização de variáveis de array.
Variável de matriz:
$var = array("abc", "def", "xyz", "123");
echo serialize($var);
Saída:
a:4:{i:0;s:3:"abc";i:1;s:3:"def";i:2;s:3:"xyz"; i:3;s:3:"123";}
é o valor da string obtido pela serialização do meu array $var. Nosso array $var inclui 4 elementos de string, a saber "abc", "def" , "xyz", "123" , vamos analisar os dados serializados, para simplificar, listamos os dados serializados em um formato de array:
a:4:
{
i:0;s:3:"abc";
i:1;s:3:"def";
i:2;s:3:"xyz";
i:3;s:3:"123";
}
A disposição é mais clara. Observe a string inicial: a:4:{...} Primeiro, o primeiro caractere a salva o tipo de variável, que é o tipo array (array), e o segundo 4 salva os elementos do array. O número de , há 4 no total e, em seguida, o conteúdo dos elementos da matriz entre {}. Por exemplo, o primeiro elemento da matriz: i:0;s:3:"abc"; i representa que o tipo de valor de índice do elemento da matriz atual é inteiro, e o valor é 0, e o tipo de valor do elemento é s (string). ), O número é 3, o valor específico é "abc", termina com ponto e vírgula e assim por diante para os seguintes elementos da matriz.
Vamos dar uma olhada no que acontece se usarmos strings como índices de elementos:
$var = array("index1"=>"abc", "index2"=>"def", "index3"=>"xyz", "index4" = >"123");
echo serialize($var);
Saída:
a:4:{s:6:"index1";s:3:"abc";s:6:"index2";s:3:"def";s:6: "index3";s:3:"xyz";s:6:"index4";s:3:"123";}
depois de mudar para o estilo array:
a:4:
{
s:6:"índice1";s:3:"abc";
s:6:"índice2";s:3:"def";
s:6:"índice3";s:3:"xyz";
s:6:"índice4";s:3:"123";
}
Na verdade, não é muito diferente do anterior, exceto que o índice inicial muda para a forma de salvar strings. Por exemplo, o primeiro elemento: s:6: "index1"; o primeiro item é o índice. Valor: s:6:"index1"; s é o tipo, 6 é o comprimento da string do índice e "index1" é o valor do índice. O seguinte s:3:"abc"; é o valor do elemento. Isso é fácil de entender, então não entrarei em detalhes.
Do exposto, temos uma compreensão geral da serialização de tipos de dados básicos. Na verdade, podemos construir nossa própria função de serialização ou expandir a partir dessa perspectiva e desenvolver nosso próprio programa de serialização para facilitar nossa troca de variáveis.
Claro, na verdade, também podemos usar esta função para serializar um array ou qualquer outra variável em uma string e, em seguida, usar a função curl para simular a função GET/POST para obter dados do servidor remoto sem que o usuário execute ações.
2. Serialização de objetos
A serialização de objetos também é uma função relativamente comum. Ela pode serializar um objeto e transformá-lo em uma string, que pode ser salva ou transmitida.
Vejamos primeiro um exemplo:
class TestClass
{
var$a;
var $b;
função ClasseTeste()
{
$this->a = "Isto é um";
$this->b = "Este é b";
}
função getA()
{
retorne $isto->a;
}
função getB()
{
retorne $isto->b;
}
}
$obj = nova ClasseTeste;
$str = serialize($obj);
echo $str;
Resultado de saída:
O:9:"TestClass":2:{s:1:"a";s:9:"Este é um";s:1:"b";s:9:"Isto is b";}
Vamos analisar a string após a serialização de um objeto.
O:9:"ClasseTeste":2:
{
s:1:"a";s:9:"Isto é um";
s:1:"b";s:9:"Este é b";
}
Primeiro observe o conteúdo do próprio objeto: O:9:"TestClass":2:O indica que este é um tipo de objeto (objeto), então 9 representa o nome do objeto e 2 representa quantos objetos existem propriedade. Observando o conteúdo dos dois atributos:
s:1:"a";s:9:"This is a"; "; é o nome do atributo de descrição. , o segundo item s:9: "This is a"; descreve o valor do atributo. As propriedades a seguir são semelhantes.
Deixe-me falar primeiro sobre uma aplicação de serialização de objetos. O conteúdo a seguir é do manual do PHP e o texto original não foi alterado.
serialize() retorna uma string contendo uma representação de fluxo de bytes de qualquer valor que pode ser armazenado em PHP. unserialize() pode usar esta string para reconstruir o valor original da variável. Salvar um objeto usando serialização salva todas as variáveis do objeto. As funções do objeto não são salvas, apenas o nome da classe.
Para poder unserialize() um objeto, a classe do objeto precisa ser definida. Ou seja, se você serializar o objeto $a da classe A em page1.php, obterá uma string apontando para a classe A e contendo os valores de todas as variáveis em $a. Se você deseja desserializá-lo em page2.php e reconstruir o objeto $a da classe A, a definição da classe A deve aparecer em page2.php. Isto pode ser conseguido, por exemplo, colocando a definição da classe A em um arquivo de inclusão e incluindo este arquivo em page1.php e page2.php.
<?php
//classa.inc:
classe A
{
var $um = 1;
função mostrar_um()
{
echo $este->um;
}
}
// página1.php:
include("classa.inc");
$a = novo A;
$s = serialize($a);
// Armazene $s em algum lugar para que page2.php possa encontrá-lo
$fp = fopen("loja", "w");
entradas($fp, $s);
fclose($fp);
// página2.php:
//Esta linha é necessária para desserialização normal
include("classa.inc");
$s = implode("", @file("store"));
$a = unserialize($s);
// Agora você pode usar a função show_one() do objeto $a
$a->show_one();
?>
Se você estiver usando uma sessão e usar session_register() para registrar objetos, esses objetos serão serializados automaticamente no final de cada página PHP e desserializados automaticamente em cada página subsequente. Basicamente, isso significa que, uma vez que esses objetos se tornem parte de uma sessão, eles poderão aparecer em qualquer página.
É altamente recomendável que todas as páginas incluam definições de classe para esses objetos registrados, mesmo que essas classes não sejam utilizadas em todas as páginas. Se isso não for feito, e um objeto for desserializado mas não tiver sua classe definida, ele perderá sua classe associada e se tornará um objeto de stdClass sem nenhuma função disponível, o que é muito inútil.
Portanto, se $a se tornar parte da sessão executando session_register("a") no exemplo acima, o arquivo classa.inc deverá ser incluído em todas as páginas, não apenas em page1.php e page2.php.
É claro que objetos serializados podem ser aplicados em muitos lugares. Claro, a serialização é tratada de forma diferente no PHP 5. Vamos dar uma olhada no que diz o manual:
serialize() verifica se existe uma função com o nome mágico __sleep na classe. Nesse caso, a função será executada antes de qualquer serialização. Ele limpa o objeto e deve retornar um array contendo os nomes de todas as variáveis do objeto que devem ser serializadas.
O objetivo de usar __sleep é fechar quaisquer conexões de banco de dados que o objeto possa ter, enviar dados pendentes ou executar tarefas de limpeza semelhantes. Além disso, esta função também é útil se você tiver objetos muito grandes que não precisam ser armazenados completamente.
Por outro lado, unserialize() verifica a existência de uma função com o nome mágico __wakeup. Esta função pode reconstruir quaisquer recursos que o objeto possa ter, se presentes.
O objetivo de usar __wakeup é restabelecer quaisquer conexões de banco de dados que possam ter sido perdidas durante a serialização e lidar com outras tarefas de reinicialização.