Cómo usar php serialize () y unserialize ()

125

Mi problema es muy básico.

¿No encontré ningún ejemplo para satisfacer mis necesidades en cuanto a qué significa exactamente serialize()y unserialize()en PHP? Solo dan un ejemplo: serializan una matriz y muestran una salida en un formato inexplicable. Es realmente difícil entender el concepto básico que pasa por su jerga.

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);

?>

salida:

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";}

No puedo entender la segunda salida. Además de eso, ¿alguien puede dar un ejemplo de una situación en la que necesito serializar una matriz php antes de usarla?

Istiaque Ahmed
fuente
10
En caso de que todavía tuviera curiosidad acerca de la "salida secundaria", es bastante simple: a = matriz, 3 = de tamaño tres elementos dentro de los {} 's. dentro de eso, tienes i = entero / índice igual a 1, cadena de len 6 igual a "elem 1", entero igual a 2 .. etc. etc. Es bastante claro cuando lo lees así. Puede imaginar múltiples niveles de matrices / objetos contenidos fácilmente, sin embargo, la modificación es muy imprudente, realmente debe deserializar la modificación y luego serializar para garantizar la coherencia.
Grizly
2
@IstiaqueAhmed, con respecto a "alguien puede dar un ejemplo de una situación en la que necesito serializar una matriz php antes de usarla" , hay un ejemplo en stackoverflow.com/a/30436890/632951
Pacerier
gracias hombre @grizly, he estado buscando una respuesta como que desde hace dos años, no sabía cómo explicarlo ni cómo asociar la razón para utilizar esta característica, gracias por la respuesta
isaacewing

Respuestas:

169

Una matriz u objeto PHP u otra estructura de datos compleja no se puede transportar, almacenar ni utilizar fuera de un script PHP en ejecución . Si desea persistir una estructura de datos tan compleja más allá de una sola ejecución de un script, debe serializarla . Eso solo significa poner la estructura en un "mínimo común denominador" que puede ser manejado por otras cosas que no sean PHP, como bases de datos, archivos de texto, sockets. La función PHP estándar serializees solo un formato para expresar tal cosa, serializa una estructura de datos en una representación de cadena que es exclusiva de PHP y se puede revertir en un objeto PHP usando unserialize. Sin embargo, hay muchos otros formatos, como JSON o XML.


Tome por ejemplo este problema común:

¿Cómo paso una matriz PHP a Javascript?

PHP y Javascript solo pueden comunicarse a través de cadenas. Puede pasar la cadena "foo"muy fácilmente a Javascript. Puede pasar el número 1muy fácilmente a Javascript. Puede pasar los valores booleanos truey falsefácilmente a Javascript. Pero, ¿cómo se pasa esta matriz a Javascript?

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

La respuesta es la serialización . En el caso de PHP / Javascript, JSON es en realidad el mejor formato de serialización:

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

Javascript puede revertir esto fácilmente en una matriz de Javascript real.

Sin embargo, esta es una representación igual de válida de la misma estructura de datos:

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

Pero prácticamente solo PHP lo usa, hay poco soporte para este formato en cualquier otro lugar.
Sin embargo, esto es muy común y está bien respaldado:

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

Hay muchas situaciones en las que necesita pasar estructuras de datos complejas como cadenas. La serialización, que representa estructuras de datos arbitrarias como cadenas, resuelve cómo hacer esto.

difunto
fuente
1
Su explicación parece acercarse a lo que esperaba. ¿Puedes echar un vistazo a mi edición?
Istiaque Ahmed
1
¿Cuál es la explicación de esos a, i, s, etc. en a: 3: {i: 1; s: 6: "elem 1"; i: 2; s: 6: "elem 2"; i: 3; s: 7: "elem 3";}? Y si no le importa, un ejemplo de serialización de la matriz (puede no ser relevante para el tema de esta publicación) para enviarlo a js.
Istiaque Ahmed
2
Hasta donde sé, apenas se puede encontrar una especificación formal de ese formato, pero puedes adivinar, ¿no? i:1= entero 1, s:6:"elem 1"= cadena con 6 caracteres "elem 1" ... ¿Y qué ejemplo está pidiendo, pensé que le di uno?
deceze
"¿Pero cómo se pasa esta matriz a Javascript? Matriz ([1] => elem 1 [2] => elem 2 [3] => elem 3)" ... solo el fragmento de código exacto para ella
Istiaque Ahmed
echo json_encode($array);Cómo lo pasas exactamente depende de las circunstancias. No te obsesiones con eso.
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);

Lo que te da una salida algo como esto

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;}}}

de nuevo si desea recuperar la matriz original, simplemente use la función PHP unserialize ()

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

Espero que esto sea de ayuda

tipico
fuente
7

Cuando desea que su valor php sea almacenable, debe convertirlo en un valor de cadena, eso es lo que hace serialize () . Y unserialize () hace lo contrario.

xdazz
fuente
1
'almacenable' ¿qué significa? Había pasado por la página que me referiste. ¿puede mostrar un ejemplo en php y mysql (si es necesario)?
Istiaque Ahmed
2
@Istiaque Ahmed Por ejemplo, cuando desea almacenar una matriz en un archivo en el disco, no puede guardar la matriz directamente sino convertirla en un valor almacenable y eso es una cadena.
xdazz
pero podemos insertar directamente una variable en la base de datos sin serializarla en php mysql. explicación por favor.
Istiaque Ahmed
9
"Podemos insertar una variable en la base de datos sin serializarla" . Esto es cierto solo para los tipos de datos fundamentales (cadenas, enteros, números). No podemos insertar matrices y objetos directamente en DB o sistema de archivos. Eso es lo que serialize()y unserialize()se hacen para.
lorenzo-s
Tomas información y trabajas con ella en tu script php, lista para almacenarla / enviarla a algún lado. Tiene la opción de crear una tabla que coincida exactamente con los datos esperados, pero esto es tedioso, esencialmente está duplicando su carga de trabajo porque también tiene que escribir un código que coincida, además los cambios en la base de datos necesitan cambios en el código o viceversa. Cuando se serializa, simplemente puede crear una tabla con dos columnas id int (10) e información BLOB. Serialise le proporciona una cadena para insertar y deserializar devuelve los datos a su estado original. Hay casos que no, los documentos php cubren esos.
Chris
7
<?php
$a= array("1","2","3");
print_r($a);
$b=serialize($a);
echo $b;
$c=unserialize($b);
print_r($c);

Ejecute este programa su eco la salida

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


aquí
a = tamaño de la matriz
i = conteo del número de matriz
s = tamaño de los valores de la matriz

puede usar serializar para almacenar una matriz de datos en la base de datos
y puede recuperar y serializar datos UN para usar.

Manikandan
fuente
6

La mayoría de los medios de almacenamiento pueden almacenar tipos de cadenas . No pueden almacenar directamente una estructura de datos PHP, como una matriz u objeto, y no deberían, ya que eso acoplaría el medio de almacenamiento de datos con PHP.

En cambio, le serialize()permite almacenar una de estas estructuras como una cadena. Se puede deserializar de su representación de cadena con unserialize().

Si está familiarizado con json_encode()y json_decode()(y JSON en general), el concepto es similar.

alex
fuente
familiarizado con json. Todavía oscuridad en el php.
edité
¿Por qué es necesario serializar si hay un json_encode? Por favor explique si lo sabe. Gracias.
Yevgeniy Afanasyev
1
@YevgeniyAfanasyev Quizás no lo haga para algunos subconjuntos de datos. Pero creo que serialize()es anterior a JSON.
alex
5

¡Por favor! ¡Por favor! ¡Por favor! NO serialice datos ni los coloque en su base de datos. Serialize se puede usar de esa manera, pero eso no tiene en cuenta una base de datos relacional y los tipos de datos inherentes a su motor de base de datos. Hacer esto hace que los datos en su base de datos no sean portátiles, difíciles de leer y puede complicar las consultas. Si desea que su aplicación sea portátil a otros idiomas, por ejemplo, supongamos que desea usar Java para alguna parte de su aplicación en la que tenga sentido usar Java, la serialización se convertirá en un problema en las nalgas. Siempre debe poder consultar y modificar datos en la base de datos sin utilizar una herramienta intermedia de terceros para manipular los datos que se insertarán.

hace que sea realmente difícil mantener el código, el código con problemas de portabilidad y los datos que son más difíciles de migrar a otros sistemas RDMS, nuevo esquema, etc. También tiene la desventaja adicional de hacer que sea desordenado buscar en su base de datos en base a uno de los campos que has serializado.

Eso no quiere decir que serialize () sea inútil. No es ... Un buen lugar para usarlo puede ser un archivo de caché que contiene el resultado de una operación intensiva de datos, por ejemplo. Hay toneladas de otros ... Simplemente no abuses de serializar porque el próximo tipo que venga tendrá una pesadilla de mantenimiento o migración.

Un buen ejemplo de serialize () y unserialize () podría ser así:

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

Deserializar en la página

if($_GET['x']) {
   // unpack serialize and encoded URL
   $_POST = unserialize(base64_decode($_GET['x']));
}
Alok avnish
fuente
2
El código provisto contiene varias vulnerabilidades de seguridad, se debe advertir a las personas que vienen y copian el código de pegado.
Daniel W.
El código dado es solo un ejemplo de cómo usar la función de búsqueda y deserialización.
Avnish alok
2

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

Genera una representación almacenable de un valor. Esto es útil para almacenar o pasar valores PHP sin perder su tipo y estructura.

Esencialmente, toma una matriz u objeto php y lo convierte en una cadena (que luego puede transmitir o almacenar como mejor le parezca).

Unserialize se utiliza para convertir la cadena de nuevo a un objeto.

MrGlass
fuente
¿Cuál es la explicación de 'representación almacenable'?
Istiaque Ahmed
Solo he visto la serialización utilizada cuando alguien quería tomar una matriz php y almacenarla en una base de datos. Puede serializar, almacenar la salida en un campo de cadena estándar en su base de datos, y luego tomarla y deserializarla cuando desee usarla nuevamente.
MrGlass
1

Básicamente, cuando serializa matrices u objetos, simplemente lo convierte a un formato de cadena válido para que pueda almacenarlos fácilmente fuera del script php.

  1. Use serializar para guardar el estado de un objeto en la base de datos (tomemos la clase Usuario como ejemplo) Luego, deserialice los datos para volver a cargar el estado anterior en el objeto (los métodos no son serializadores; debe incluir la clase de objeto para poder usar eso)
    • personalización del usuario

Nota para el objeto, debe usar los métodos mágicos __sleep y __wakeup. __sleep se llama por serialize (). Un método de suspensión devolverá una matriz de valores del objeto que desea persistir.

__wakeup es llamado por unserialize (). Un método de activación debe tomar los valores no serializados e inicializarlos en el objeto.

Para pasar datos entre php y js, usaría json_encode para convertir la matriz php a un formato json válido. O al revés: use JSON.parese () para convertir un dato de salida (cadena) en un objeto json válido. Desea hacer eso para hacer uso del almacenamiento local. (acceso a datos sin conexión)

DevWL
fuente
¿Por qué es necesario serializar si hay un json_encode? Por favor explique si lo sabe. Gracias.
Yevgeniy Afanasyev
1
Puede beneficiarse de poder personalizar el método mágico que se combina cuando se usa serializar y no serializar. Dicho esto, puede tomar Json_encode () y json_decode () mucho más lejos y cada objeto puede manejar estos functinos de una manera única. Por eso te gustaría usarlos.
DevWL
1
Hay más, mucho más. Consulte esta respuesta para obtener más información stackoverflow.com/questions/804045/…
DevWL
1
json_encode es más rápido (depende de la versión de PHP que esté utilizando), json decodifica como stdClass, el objeto serilizado no se serializa como una instancia de clase real, alguna configuración se me ha hecho a JSON para preservar la codificación UTF-8 sin cambios, la serialización no cambia la codificación. Si desea hacer que los datos multiplataforma usen JSON, si trabaja solo en PHP, puede usar el método mágico __sleep y __wakeup para personalizar la serialización.
DevWL
0

Sí, puedo. Supongamos que necesitamos rastrear su sistema significa que en su sistema tiene más de un administrador y un subadmin, todos estos pueden insertar o actualizar o editar cualquier información. Más tarde necesita saber quién realiza este cambio. Para resolver este problema necesita 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)

Espero que esto ayude.


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