Сериализация, вероятно, заключается в преобразовании некоторых переменных в поток байтов строк, что упрощает передачу и хранение. Конечно, здесь нет ничего общего с передачей и хранением. Ключевым моментом является то, что его можно преобразовать обратно в строковую форму и сохранить исходную структуру данных.
В PHP существует множество функций сериализации: Serialize(). Эта функция преобразует любое значение переменной (кроме переменных ресурса) в форму строки. Строку можно сохранить в файл, зарегистрировать как сеанс или даже использовать для этого Curl. имитируйте GET/POST для передачи переменных для достижения эффекта RPC.
Если вы хотите преобразовать сериализованные переменные в исходные значения переменных PHP, вы можете использовать функцию unserialize().
1. Сериализация переменных
Давайте рассмотрим простой пример, чтобы проиллюстрировать сериализацию и формат ее хранения.
Целочисленный тип:
$var = 23;
echo сериализация($var);
Выход:
i:23;
Тип с плавающей запятой:
$
var = 1.23;
echoсериализация
($var);
Выход:
d:1.22999999999999982236431605997495353221893310546875;
эхо-сериализация ($ var);
$var = "Я переменная";
echo seriesize($var);
Вывод:
s:16:"Это строка";
s:8: «Я переменная»
Логический тип:
$var = true;
эхо-сериализация ($ var);
$вар = ложь;
эхо сериализовать ($ var);
Вывод:
б: 1;
b:0;
Ситуация после сериализации вышеуказанных базовых типов очень ясна. Формат хранения после сериализации:
тип переменной:
[длина переменной:] значение переменной;
Представляет разделение. Длина переменной не является обязательной, то есть она доступна в строковом типе, но не доступна в других типах. Последнее значение переменной. Каждое сериализованное значение заканчивается знаком ";".
Например, после сериализации нашего целого числа 23 оно имеет вид: i:23, тогда оно не имеет длины, только тип и значение переменной, i представляет целое число, разделенное двоеточием, а целочисленное значение 23 сохраняется позже, включая плавающую точку. тип (двойной) Байтовый тип) тот же. Для Boolean типом является b (логическое значение). Если оно истинно, сериализованное значение равно 1. Если оно ложно, значение равно 0.
Для
строковых
значений в середине будет дополнительное сохраненное значение, в котором сохраняется значение длины строки, например строка «Это строка», тогда сгенерированное сериализованное значение будет s:16: «Это строка». "; s — строка, представляющая тип. 16 в середине — это длина строки. Если она китайская, то каждый китайский иероглиф хранится в двух символах. Например, строка «Я — переменная», сгенерированное сериализованное значение: :s:8:"Я переменная"; его длина составляет 8 символов.Далее мы сосредоточимся на сериализации переменных массива.
Переменная-массив:
$var = array("abc", "def", "xyz", "123");
echo seriesize($var);
Выход:
a:4:{i:0;s:3:"abc";i:1;s:3:"def";i:2;s:3:"xyz"; i:3;s:3:"123";}
— это строковое значение, полученное путем сериализации моего массива $var. Наш массив $var включает в себя 4 строковых элемента, а именно «abc», «def», «xyz», «123». , давайте проанализируем сериализованные данные. Для простоты мы перечислим сериализованные данные в формате массива:
a:4:
{
я:0;s:3:"abc";
я:1;s:3:"def";
я:2;s:3:"xyz";
я:3;с:3:"123";
}
Порядок более понятен. Посмотрите на начальную строку: a:4:{...} Первый символ a сохраняет тип переменной, который является типом массива (массива), а вторые 4 — элементы массива. Число , всего их 4, а затем содержимое элементов массива между {}. Например, первый элемент массива: i:0;s:3:"abc"; i представляет, что тип значения индекса текущего элемента массива является целочисленным, значение равно 0, а тип значения элемента — s (строка ), Число — 3, конкретное значение — «abc», заканчивается точкой с запятой и т. д. для следующих элементов массива.
Давайте посмотрим, что произойдет, если мы используем строки в качестве индексов элементов:
$var = array("index1"=>"abc", "index2"=>"def", "index3"=>"xyz", "index4" =>"123");
echo serize($var);
Выход:
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";}
после перехода на стиль массива:
a:4:
{
s:6:"индекс1";s:3:"abc";
s:6:"index2";s:3:"def";
s:6:"index3";s:3:"xyz";
с:6:"индекс4";с:3:"123";
}
По сути, он мало чем отличается от вышеописанного, за исключением того, что начальный индекс меняется на форму сохранения строк. Например, первый элемент: s:6: "index1"; s:3: "abc"; первый элемент — это индекс. Значение: s:6:"index1"; s — тип, 6 — длина индексной строки, а «index1» — значение индекса. Следующее значение s:3:"abc"; Это легко понять, поэтому я не буду вдаваться в подробности.
Из вышеизложенного у нас есть общее представление о сериализации базовых типов данных. Фактически мы можем создать собственную функцию сериализации или расширить ее с этой точки зрения и разработать собственную программу сериализации для облегчения обмена переменными.
Конечно, на самом деле мы также можем использовать эту функцию для сериализации массива или любой другой переменной в строку, а затем использовать функцию Curl для имитации функции GET/POST для получения данных с удаленного сервера без выполнения действий пользователем.
2. Сериализация объекта
Сериализация объекта также является относительно распространенной функцией. Она может сериализовать объект и превратить его в строку, которую можно сохранить или передать.
Давайте сначала рассмотрим пример:
класс TestClass
{
вар $а;
вар $б
функция TestClass();
{
$this->a = "Это";
$this->b = "Это b";
}
функция getA()
{
верните $this->a;
}
функция getB()
{
верните $this->b;
}
}
$obj = новый TestClass;
$str = сериализовать($obj);
echo $str;
Результат вывода:
O:9:"TestClass":2:{s:1:"a";s:9:"Это a";s:1:"b";s:9:"Это is b";}
Проанализируем строку после сериализации объекта.
О:9:"ТестКласс":2:
{
s:1:"а";s:9:"Это а";
s:1:"б";s:9:"Это б";
}
Сначала посмотрите на содержимое самого объекта: O:9:"TestClass":2:O указывает, что это тип объекта (объект), затем 9 представляет имя объекта, а 2 представляет количество имеющихся объектов. свойство. Глядя на содержимое двух атрибутов:
s:1:"a";s:9:"This is a"; Фактически оно похоже на содержимое первого элемента: s:1:"a. "; — имя атрибута описания. , второй элемент s:9: "This is a"; описывает значение атрибута. Следующие свойства аналогичны.
Позвольте мне сначала рассказать о применении сериализации объектов. Следующее содержание взято из руководства по PHP, исходный текст не был изменен.
Serialize() возвращает строку, содержащую представление потока байтов любого значения, которое может быть сохранено в PHP. unserialize() может использовать эту строку для восстановления исходного значения переменной. При сохранении объекта с использованием сериализации сохраняются все переменные объекта. Функции в объекте не сохраняются, только имя класса.
Чтобы иметь возможность unserialize() объекта, необходимо определить класс объекта. То есть, если вы сериализуете объект $a класса A в page1.php, вы получите строку, указывающую на класс A и содержащую значения всех переменных в $a. Если вы хотите десериализовать его в page2.php и восстановить объект $a класса A, определение класса A должно появиться в page2.php. Этого можно добиться, например, поместив определение класса A во включаемый файл и включив этот файл как в page1.php, так и в page2.php.
<?php
// классa.inc:
класс А
{
вар $one = 1;
функция show_one();
{
эхо $this->one;
}
}
// страница1.php:
include("classa.inc");
$a = новый A;
$s = сериализовать($а);
// Сохраняем где-нибудь $s, чтобы page2.php мог его найти
$fp = fopen("магазин", "w");
fputs($fp, $s);
fclose($fp);
// страница2.php:
// Эта строка нужна для нормальной десериализации
include("classa.inc");
$s = implode("", @file("store"));
$a = unserialize($s);
// Теперь вы можете использовать функцию show_one() объекта $a.
$a->show_one();
?>
Если вы используете сеанс и используете session_register() для регистрации объектов, эти объекты будут автоматически сериализоваться в конце каждой страницы PHP и автоматически десериализоваться на каждой последующей странице. По сути, это означает, что как только эти объекты станут частью сеанса, они смогут появиться на любой странице.
Настоятельно рекомендуется, чтобы все страницы включали определения классов для этих зарегистрированных объектов, даже если эти классы не используются на всех страницах. Если этого не сделать и объект десериализован, но не имеет определенного класса, он потеряет связанный с ним класс и станет объектом stdClass вообще без каких-либо доступных функций, что очень бесполезно.
Таким образом, если $a становится частью сеанса при запуске session_register("a") в приведенном выше примере, файл classa.inc должен быть включен во все страницы, а не только на page1.php и page2.php.
Конечно, сериализованные объекты можно применять во многих местах. Конечно, в PHP 5 сериализация обрабатывается по-другому. Давайте посмотрим, что написано в руководстве:
сериализация() проверяет, есть ли в классе функция с магическим именем __sleep. Если это так, функция будет запущена до любой сериализации. Он очищает объект и должен вернуть массив, содержащий имена всех переменных в объекте, который необходимо сериализовать.
Цель использования __sleep — закрыть любые соединения с базой данных, которые может иметь объект, отправить ожидающие данные или выполнить аналогичные задачи очистки. Кроме того, эта функция также полезна, если у вас очень большие объекты, которые не нужно сохранять полностью.
И наоборот, unserialize() проверяет наличие функции с магическим именем __wakeup. Эта функция может реконструировать любые ресурсы, которые может иметь объект, если они есть.
Цель использования __wakeup — восстановить любые соединения с базой данных, которые могли быть потеряны во время сериализации, и выполнить другие задачи повторной инициализации.