La serialización probablemente consiste en convertir algunas variables en un flujo de bytes de cadenas, lo que facilita su transmisión y almacenamiento. Por supuesto, no tiene nada que ver con la transmisión y el almacenamiento. La clave es que se puede volver a convertir en forma de cadena y se puede mantener la estructura de datos original.
Hay muchas funciones de serialización en PHP: serialize() Esta función convierte cualquier valor de variable (excepto las variables de recursos) en forma de cadena. La cadena se puede guardar en un archivo, o registrarse como una sesión, o incluso usar curl para. Simule GET / POST para transferir variables para lograr el efecto de RPC.
Si desea convertir variables serializadas en valores de variables originales de PHP, puede utilizar la función unserialize().
1. Serialización de variables
Tomemos un ejemplo sencillo para ilustrar la serialización y su formato de almacenamiento.
Tipo de entero:
$var = 23;
echo serialize($var);
Salida
:
i:23;
Tipo de punto flotante:
$var = 1.23;
echo
serialize
($var)
;
eco serializar($var);
$var = "Soy una variable";
echo serialize($var);
Salida:
s:16:"Esto es una cadena";
s:8: "Soy una variable";
tipo booleano:
$var = verdadero;
eco serializar($var);
$var = falso;
echo serializar($var);
Salida:
b:1;
b:0;
La situación después de la serialización de los tipos básicos anteriores es muy clara. El formato de almacenamiento después de la serialización es:
tipo de variable: [longitud de variable:] valor de variable,
es decir, el primer carácter representa el tipo de variable; Representa la división. La longitud de la variable es opcional, es decir, está disponible en el tipo de cadena pero no en otros tipos. El último es el valor de la variable que termina en ";".
Por ejemplo, después de serializar nuestro número entero 23, es: i: 23, entonces no tiene longitud, solo tipo y valor de variable, i representa un número entero, separado por dos puntos, y el valor entero 23 se guarda más tarde, incluido el punto flotante. tipo (doble) Tipo de byte) es el mismo. Para booleano, el tipo es b (booleano). Si es verdadero, el valor serializado es 1. Si es falso, el valor es 0.
Para los valores
de cadena
, habrá un valor guardado adicional en el medio, que guarda el valor de longitud de la cadena, como la cadena "Esta es una cadena", luego el valor serializado generado es s:16: "Esta es una cadena "; s es una cadena que representa el tipo. El 16 en el medio es la longitud de la cadena. Si es chino, cada carácter chino se almacena en dos caracteres. Por ejemplo, la cadena "Soy una variable", el valor serializado generado es :s:8:"Soy una variable"; tiene 8 caracteres de longitud.A continuación nos centramos en la serialización de variables de matriz.
Variable de matriz:
$var = matriz("abc", "def", "xyz", "123");
echo serialize($var);
Salida:
a:4:{i:0;s:3:"abc";i:1;s:3:"def";i:2;s:3:"xyz"; i:3;s:3:"123";}
es el valor de cadena obtenido al serializar mi matriz $var. Nuestra matriz $var incluye 4 elementos de cadena, a saber, "abc", "def", "xyz", "123" , analicemos los datos serializados Para simplificar, enumeramos los datos serializados en un formato de matriz:
a:4:
{
i:0;s:3:"abc";
i:1;s:3:"definición";
i:2;s:3:"xyz";
i:3;s:3:"123";
}
La disposición es más clara Mire la cadena inicial: a:4:{...} Primero, el primer carácter a guarda el tipo de variable, que es el tipo de matriz (matriz), y los segundos 4 guardan los elementos de la matriz. El número de, hay 4 en total, y luego el contenido de los elementos de la matriz entre {}. Por ejemplo, el primer elemento de la matriz: i:0;s:3:"abc"; i representa que el tipo de valor de índice del elemento de la matriz actual es entero, el valor es 0 y el tipo de valor del elemento es s (cadena). ), El número es 3, el valor específico es "abc", termina con punto y coma, y así sucesivamente para los siguientes elementos de la matriz.
Echemos un vistazo a lo que sucede si usamos cadenas como índices de elementos:
$var = array("index1"=>"abc", "index2"=>"def", "index3"=>"xyz", "index4" =>"123");
echo serialize($var);
Salida:
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";}
después de cambiar al estilo de matriz:
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";
}
De hecho, no es muy diferente de lo anterior, excepto que el índice inicial cambia a la forma de guardar cadenas. Por ejemplo, el primer elemento: s:6: "index1"; El primer elemento es el índice. s:6:"index1"; s es el tipo, 6 es la longitud de la cadena de índice y "index1" es el valor del índice. El siguiente s:3:"abc"; es el valor del elemento. Esto es fácil de entender, por lo que no entraré en detalles.
De lo anterior, tenemos una comprensión general de la serialización de tipos de datos básicos. De hecho, podemos construir nuestra propia función de serialización, o expandirnos desde esta perspectiva y desarrollar nuestro propio programa de serialización para facilitar nuestro intercambio de variables.
Por supuesto, de hecho, también podemos usar esta función para serializar una matriz o cualquier otra variable en una cadena, y luego usar la función curl para simular la función GET/POST para obtener datos del servidor remoto sin que el usuario realice acciones.
2. Serialización de objetos
La serialización de objetos también es una función relativamente común. Puede serializar un objeto y convertirlo en una cadena, que puede guardarse o transmitirse.
Primero veamos un ejemplo:
clase TestClass
{
var$a;
var $b;
función Clase de prueba()
{
$this->a = "Esto es un";
$this->b = "Esto es b";
}
función obtenerA()
{
devolver $this->a;
}
función obtenerB()
{
devolver $this->b;
}
}
$obj = nueva Clase de Prueba;
$cadena = serializar($obj);
echo $str;
Resultado de salida:
O:9:"TestClass":2:{s:1:"a";s:9:"Esto es un";s:1:"b";s:9:"Esto es b";}
Analicemos la cadena después de la serialización de un objeto.
O:9:"Clase de prueba":2:
{
s:1:"a";s:9:"Esto es un";
s:1:"b";s:9:"Esto es b";
}
Primero mire el contenido del objeto en sí: O:9:"TestClass":2:O indica que este es un tipo de objeto (objeto), luego 9 representa el nombre del objeto y 2 representa cuántos objetos hay propiedad. Mirando el contenido de los dos atributos:
s:1:"a";s:9:"This is a"; De hecho, es similar al contenido de la matriz. "; es el nombre del atributo de descripción. , el segundo elemento s:9: "Esto es un"; describe el valor del atributo. Las siguientes propiedades son similares.
Permítanme hablar primero sobre una aplicación de serialización de objetos. El siguiente contenido es del manual de PHP y el texto original no ha sido modificado.
serialize() devuelve una cadena que contiene una representación de flujo de bytes de cualquier valor que pueda almacenarse en PHP. unserialize() puede usar esta cadena para reconstruir el valor de la variable original. Guardar un objeto mediante serialización guarda todas las variables del objeto. Las funciones del objeto no se guardan, sólo el nombre de la clase.
Para poder deserializar() un objeto, es necesario definir la clase del objeto. Es decir, si serializa el objeto $a de la clase A en page1.php, obtendrá una cadena que apunta a la clase A y que contiene los valores de todas las variables en $a. Si desea deserializarlo en page2.php y reconstruir el objeto $a de la clase A, la definición de la clase A debe aparecer en page2.php. Esto se puede lograr, por ejemplo, colocando la definición de clase A en un archivo de inclusión e incluyendo este archivo tanto en page1.php como en page2.php.
<?php
// classa.inc:
clase A
{
var $uno = 1;
función mostrar_uno();
{
echo $este->uno;
}
}
// página1.php:
incluir("classa.inc");
$a = nueva A;
$s = serializar($a);
// Almacena $s en algún lugar para que page2.php pueda encontrarlo
$fp = fopen("tienda", "w");
fputs($fp, $s);
fclose($fp);
// página2.php:
// Esta línea es necesaria para la deserialización normal
include("classa.inc");
$s = implosionar("", @file("tienda"));
$a = unserialize($s);
// Ahora puedes usar la función show_one() del objeto $a
$a->mostrar_uno();
?>
Si está utilizando una sesión y utiliza session_register() para registrar objetos, estos objetos se serializarán automáticamente al final de cada página PHP y se deserializarán automáticamente en cada página posterior. Básicamente, esto significa que una vez que estos objetos pasan a formar parte de una sesión, pueden aparecer en cualquier página.
Se recomienda encarecidamente que todas las páginas incluyan definiciones de clases para estos objetos registrados, incluso si estas clases no se utilizan en todas las páginas. Si no se hace esto y se deserializa un objeto pero no tiene su clase definida, perderá su clase asociada y se convertirá en un objeto de stdClass sin ninguna función disponible, lo cual es muy inútil.
Entonces, si $a se convierte en parte de la sesión ejecutando session_register("a") en el ejemplo anterior, el archivo classa.inc debe incluirse en todas las páginas, no solo en page1.php y page2.php.
Por supuesto, los objetos serializados se pueden aplicar en muchos lugares. Por supuesto, la serialización se maneja de manera diferente en PHP 5. Echemos un vistazo a lo que dice el manual:
serialize() verifica si hay una función con el nombre mágico __sleep en la clase. Si es así, la función se ejecutará antes de cualquier serialización. Borra el objeto y debería devolver una matriz que contenga los nombres de todas las variables del objeto que deberían serializarse.
El propósito de usar __sleep es cerrar cualquier conexión a la base de datos que pueda tener el objeto, enviar datos pendientes o realizar tareas de limpieza similares. Además, esta función también es útil si tienes objetos muy grandes que no es necesario almacenar por completo.
Por el contrario, unserialize() comprueba la existencia de una función con el nombre mágico __wakeup. Esta función puede reconstruir cualquier recurso que pueda tener el objeto, si está presente.
El propósito de utilizar __wakeup es restablecer cualquier conexión de base de datos que se haya perdido durante la serialización y manejar otras tareas de reinicialización.