Como usar php serialize () e unserialize ()

125

Meu problema é muito básico.

Não encontrei nenhum exemplo para atender às minhas necessidades sobre o que exatamente serialize()e o que unserialize()significa em php? Eles apenas dão um exemplo - serializam uma matriz e mostram uma saída em um formato inexplicável. É realmente difícil entender o conceito básico do jargão deles.

EDITAR:

<?php

$a= array( '1' => 'elem 1', '2'=> 'elem 2', '3'=>' elem 3');
print_r($a);
echo ("<br></br>");
$b=serialize($a);
print_r($b);

?>

resultado:

Array ( [1] => elem 1 [2] => elem 2 [3] => elem 3 ) 

a:3:{i:1;s:6:"elem 1";i:2;s:6:"elem 2";i:3;s:7:" elem 3";}

Não consigo entender a segunda saída. Além disso, alguém pode dar um exemplo de uma situação em que eu preciso serializar um array php antes de usá-lo?

Istiaque Ahmed
fonte
10
Caso você ainda estivesse curioso sobre a "saída secundária", é bastante simples: a = array, 3 = do tamanho três elementos dentro do {} 's. dentro disso, você tem i = número inteiro / índice igual a 1, sequência de len 6 igual a "elem 1", número inteiro igual a 2 .. etc etc .. É bastante claro quando você lê dessa maneira. Você pode imaginar vários níveis de matrizes / objetos sendo facilmente contidos, no entanto, a modificação é muito imprudente; você deve realmente desserializar modificar e serializar para garantir consistência.
Grizly
2
@IstiaqueAhmed, Em relação a "alguém pode dar um exemplo de uma situação em que eu preciso serializar uma matriz php antes de usá-la" , existe um exemplo em stackoverflow.com/a/30436890/632951
Pacerier
@grizly graças cara, eu estou procurando uma resposta assim há dois anos, eu não sabia como explicá-la nem como associar o motivo de usar esse recurso, obrigado pela resposta
isaacewing

Respostas:

169

Uma matriz ou objeto PHP ou outra estrutura de dados complexa não pode ser transportada ou armazenada ou usada fora de um script PHP em execução . Se você quiser manter uma estrutura de dados tão complexa além de uma única execução de um script, precisará serializá- la. Isso significa apenas colocar a estrutura em um "denominador comum inferior" que pode ser manipulado por outras coisas que não o PHP, como bancos de dados, arquivos de texto, soquetes. A função PHP padrão serializeé apenas um formato para expressar isso, serializa uma estrutura de dados em uma representação de string exclusiva do PHP e pode ser revertida em um objeto PHP usando unserialize. Existem muitos outros formatos, como JSON ou XML.


Tomemos, por exemplo, este problema comum:

Como passo uma matriz PHP para Javascript?

PHP e Javascript podem se comunicar apenas através de strings. Você pode passar a string com "foo"muita facilidade para Javascript. Você pode passar o número 1muito facilmente para Javascript. Você pode passar os valores booleanos truee falsefacilmente para Javascript. Mas como você passa essa matriz para Javascript?

Array ( [1] => elem 1 [2] => elem 2 [3] => elem 3 ) 

A resposta é serialização . No caso de PHP / Javascript, JSON é realmente o melhor formato de serialização:

{ 1 : 'elem 1', 2 : 'elem 2', 3 : 'elem 3' }

O Javascript pode facilmente reverter isso para uma matriz Javascript real.

Esta é uma representação igualmente válida da mesma estrutura de dados:

a:3:{i:1;s:6:"elem 1";i:2;s:6:"elem 2";i:3;s:7:" elem 3";}

Mas praticamente apenas o PHP o usa, há pouco suporte para esse formato em qualquer outro lugar.
Isso é muito comum e bem suportado, embora:

<array>
    <element key='1'>elem 1</element>
    <element key='2'>elem 2</element>
    <element key='3'>elem 3</element>
</array>

Existem muitas situações em que você precisa passar estruturas de dados complexas como strings. A serialização, representando estruturas de dados arbitrárias como seqüências de caracteres, resolve como fazer isso.

deceze
fonte
1
Nossa explicação parece estar se aproximando do que eu esperava. você pode dar uma olhada na minha edição?
Istiaque Ahmed
1
qual é a explicação daqueles a, i, s etc em a: 3: {i: 1; s: 6: "elem 1"; i: 2; s: 6: "elem 2"; i: 3; s: 7: "elem 3";}? E se você não se importa, um exemplo de serializar o array (pode não ser relevante para o tema deste post) para enviá-lo para js.
Istiaque Ahmed 27/12/11
2
Tanto quanto sei, dificilmente existe uma especificação formal desse formato, mas você pode adivinhar, não é? i:1= inteiro 1, s:6:"elem 1"= string com 6 caracteres "elem 1" ... E que exemplo você está pedindo, pensei em dar um?
deceze
"Mas como você passa essa matriz para Javascript? Matriz ([1] => elem 1 [2] => elem 2 [3] => elem 3)" ... exatamente o trecho de código exato para ela
Istiaque Ahmed
echo json_encode($array);Como exatamente você passa depende das circunstâncias. Não fique muito preocupado com isso.
deceze
27

PHP serialize () unserialize () uso

http://freeonlinetools24.com/serialize

echo '<pre>';
// say you have an array something like this 
$multidimentional_array= array(
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 4, 7) 
       ),
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 5, 7) 
       ),
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 8, 7) 
    )
);

// serialize 
$serialized_array=serialize($multidimentional_array);
print_r($serialized_array);

O que lhe dá uma saída parecida com esta

a:3:{i:0;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:4;i:2;i:7;}}i:1;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:5;i:2;i:7;}}i:2;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:8;i:2;i:7;}}}

novamente, se você deseja recuperar a matriz original, basta usar a função PHP unserialize ()

$original_array=unserialize($serialized_array);
var_export($original_array);

Espero que isso ajude

tipico
fonte
7

Quando você deseja tornar seu valor php armazenável, você deve transformá-lo em um valor de string, é o que serialize () faz. E unserialize () faz o contrário.

xdazz
fonte
1
'armazenável' o que isso significa? Eu tinha percorrido a página que você indicou. u pode mostrar um exemplo em php e mysql (se necessário)?
Istiaque Ahmed 27/12/11
2
@Istiaque Ahmed Por exemplo, quando você deseja armazenar uma matriz em um arquivo no disco, não pode salvar a matriz diretamente, mas transformá-la em um valor armazenável e isso é uma string.
Xdazz
mas podemos inserir diretamente uma variável no banco de dados sem serializá-la no php mysql. explicação por favor.
Istiaque Ahmed 27/12/11
9
"Podemos inserir uma variável no banco de dados sem serializá-la" . Isso é verdadeiro apenas para tipos de dados fundamentais (cadeias, número inteiro, números). Não podemos inserir matrizes e objetos diretamente no banco de dados ou no sistema de arquivos. Isso é o que serialize()e unserialize()são feitos para.
Lorenzo-s
Você pega algumas informações e trabalha com elas em seu script php, pronto para armazenar / enviar para algum lugar. Você tem a opção de criar uma tabela que corresponda exatamente aos dados esperados, mas é tedioso que você esteja dobrando sua carga de trabalho porque precisa escrever um código que corresponda também, além de que mudanças no banco de dados precisam de mudanças no código ou vice-versa. Quando serializado, você pode simplesmente criar uma tabela com duas colunas id int (10) e BLOB de informações. Serializar fornece uma string para inserir e desserializar retorna os dados ao seu estado original. Há casos em que não, os documentos php cobrem esses.
Chris
7
<?php
$a= array("1","2","3");
print_r($a);
$b=serialize($a);
echo $b;
$c=unserialize($b);
print_r($c);

Execute este programa seu eco da saída

a:3:{i:0;s:1:"1";i:1;s:1:"2";i:2;s:1:"3";}


aqui
a = tamanho da matriz
i = contagem do número da matriz
s = tamanho dos valores da matriz

você pode usar serializar para armazenar a matriz de dados no banco de dados
e recuperar e serializar dados UN para usar.

Manikandan
fonte
6

A maioria dos meios de armazenamento pode armazenar string tipos de . Eles não podem armazenar diretamente uma estrutura de dados PHP, como uma matriz ou objeto, e não devem, pois isso associaria o meio de armazenamento de dados ao PHP.

Em vez disso, serialize()permite armazenar uma dessas estruturas como uma sequência. Ele pode ser desserializado de sua representação de string comunserialize() .

Se você está familiarizado com json_encode()e json_decode()(e JSON em geral), o conceito é semelhante.

alex
fonte
familiarizado com json. ainda obscuridade na coisa php. editou minha publicação
Istiaque Ahmed 27/12/11
Por que é necessário serializar se houver um json_encode? Por favor, explique se você souber. Obrigado.
Yevgeniy Afanasyev
1
@YevgeniyAfanasyev Talvez você não faça isso para alguns subconjuntos de dados. Mas acho que serialize()é anterior ao JSON.
alex
5

Por favor! por favor! por favor! NÃO serialize dados e os coloque no seu banco de dados. A serialização pode ser usada dessa maneira, mas está faltando o ponto de um banco de dados relacional e os tipos de dados inerentes ao mecanismo de banco de dados. Fazer isso torna os dados em seu banco de dados não portáveis, difíceis de ler e podem complicar as consultas. Se você deseja que seu aplicativo seja portátil para outras linguagens, como digamos que você deseja usar Java para uma parte do aplicativo em que faz sentido usar Java, a serialização se tornará um problema nas nádegas. Você sempre deve poder consultar e modificar dados no banco de dados sem usar uma ferramenta intermediária de terceiros para manipular os dados a serem inseridos.

torna muito difícil manter código, código com problemas de portabilidade e dados que são mais difíceis de migrar para outros sistemas RDMS, novo esquema etc. Também tem a desvantagem adicional de dificultar a pesquisa no banco de dados com base em um dos os campos que você serializou.

Isso não quer dizer que serialize () é inútil. Não é ... Um bom lugar para usá-lo pode ser um arquivo de cache que contém o resultado de uma operação intensiva em dados, por exemplo. Existem muitos outros ... Só não abuse da serialização, porque o próximo cara que aparecer terá um pesadelo de manutenção ou migração.

Um bom exemplo de serialize () e unserialize () pode ser assim:

$posts = base64_encode(serialize($_POST));
header("Location: $_SERVER[REQUEST_URI]?x=$posts");

Anular a desserialização na página

if($_GET['x']) {
   // unpack serialize and encoded URL
   $_POST = unserialize(base64_decode($_GET['x']));
}
Avnish alok
fonte
2
O código fornecido contém várias vulnerabilidades de segurança; as pessoas que chegam e copiam o código de colagem devem ser avisadas.
Daniel W.
O código fornecido é apenas um exemplo de como usar a função searilize e desserialize.
Avnish alok
2

Em http://php.net/manual/en/function.serialize.php :

Gera uma representação armazenável de um valor. Isso é útil para armazenar ou transmitir valores PHP sem perder seu tipo e estrutura.

Essencialmente, ele pega um array ou objeto php e o converte em uma string (que você pode transmitir ou armazenar como achar melhor).

Unserialize é usado para converter a string novamente em um objeto.

MrGlass
fonte
qual é a explicação da 'representação armazenável'?
Istiaque Ahmed 27/12/11
Você só viu serializar usado quando alguém quisesse pegar um array php e armazená-lo em um banco de dados. Você pode serializar, armazenar a saída em um campo de sequência padrão no seu banco de dados e, em seguida, pegar e desserializar quando quiser usá-lo novamente.
MrGlass
1

Basicamente, quando você serializa matrizes ou objetos, basta transformá-lo em um formato de string válido, para que você possa armazená-los facilmente fora do script php.

  1. Use serialize para salvar o estado de um objeto no banco de dados (vamos tomar a classe User como exemplo) Em seguida, desserialize os dados para carregar o estado anterior no objeto (os métodos não são serializadores, é necessário incluir a classe de objeto para poder usar isto)
    • personalização do usuário

Nota para o objeto, você deve usar os métodos mágicos __sleep e __wakeup. __sleep é chamado por serialize (). Um método sleep retornará uma matriz dos valores do objeto que você deseja persistir.

__wakeup é chamado por unserialize (). Um método de ativação deve pegar os valores não serializados e inicializá-los no objeto.

Para passar dados entre php e js, você usaria json_encode para transformar o array php no formato json válido. Ou vice-versa - use JSON.parese () para converter um dado de saída (string) em um objeto json válido. Você gostaria de fazer isso para usar o armazenamento local. (acesso offline a dados)

DevWL
fonte
Por que é necessário serializar se houver um json_encode? Por favor, explique se você souber. Obrigado.
Yevgeniy Afanasyev
1
Você pode se beneficiar da possibilidade de personalizar o método mágico que é agrupado ao usar serializar e desserializar. Dito isto, você pode levar Json_encode () e json_decode () muito mais longe e cada objeto pode lidar com essa função de sua maneira única. É por isso que você gostaria de usá-los.
DevWL
1
Há muito mais que isso. Veja esta resposta para obter mais informações stackoverflow.com/questions/804045/…
DevWL
1
O json_encode é mais rápido (depende da versão do PHP que você está usando), o json decodifica como stdClass, o objeto serilizado desserializa como uma instância real da classe. Algumas configurações foram feitas no JSON para preservar a codificação UTF-8 inalterada; Se você deseja fazer com que os dados entre plataformas usem JSON, se você trabalha apenas em PHP, pode usar o método mágico __sleep e __wakeup para personalizar a serialização.
DevWL
0

Sim eu posso. Suponha que precisamos rastrear o seu sistema significa que no seu sistema há mais de um administrador e subadmin, tudo isso pode inserir, atualizar ou editar qualquer informação. Mais tarde, você precisa saber quem faz essa alteração. Para resolver esse problema, você precisa serializar.

  **Explain:**Create a table named history which stores all changes. Each time there is a change insert a new row in this table. It might have this fields:

  history(id,target_table(name of the table), target_id (ID of the saved entry),create/edit/change data (serialized data of the saved row),date)

Eu espero que isso te ajude.


fonte
-1
preg_match_all('/\".*?\"/i', $string, $matches);
foreach ($matches[0] as $i => $match) $matches[$i] = trim($match, '"');
X 47 48 - IR
fonte