Как использовать php serialize () и unserialize ()


125

Моя проблема очень проста.

Я не нашел ни одного примера, который бы соответствовал моим потребностям относительно того, что именно serialize()и unserialize()означает в php? Они просто приводят пример - сериализуют массив и показывают результат в необъяснимом формате. На их жаргоне действительно сложно понять основную концепцию.

РЕДАКТИРОВАТЬ:

<?php

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

?>

вывод:

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

Не могу понять второй вывод. Кроме того, может ли кто-нибудь привести пример ситуации, когда мне нужно сериализовать массив php перед его использованием?


10
Если вас все еще интересует «вторичный вывод», он довольно прост: a = массив, 3 = размер трех элементов внутри {}. внутри у вас есть i = целое число / индекс, равное 1, строка из len 6, равная «elem 1», целое число, равное 2 ... и т. д. Это довольно ясно, когда вы читаете это так. Вы можете представить себе несколько уровней массивов / объектов, которые легко содержатся внутри, однако модификация очень неразумна, вам действительно следует десериализовать модификацию, а затем сериализовать, чтобы обеспечить согласованность.
Grizly

2
@IstiaqueAhmed, Что касается «может ли кто-нибудь привести пример ситуации, когда мне нужно сериализовать массив php перед его использованием» , есть такой пример на stackoverflow.com/a/30436890/632951
Pacerier

@grizly, спасибо, чувак, я два года искал такой ответ, я не знал, как это объяснить и как связать причину использования этой функции, спасибо за ответ
isaacewing

Ответы:


170

Массив или объект PHP или другая сложная структура данных не могут быть транспортированы, сохранены или иным образом использованы за пределами запущенного сценария PHP . Если вы хотите сохранить такую ​​сложную структуру данных за пределами одного запуска скрипта, вам необходимо сериализовать ее. Это просто означает поместить структуру в «нижний общий знаменатель», который может обрабатываться другими вещами, кроме PHP, такими как базы данных, текстовые файлы, сокеты. Стандартная функция PHP serialize- это просто формат для выражения такой вещи, она сериализует структуру данных в строковое представление, уникальное для PHP и может быть преобразовано в объект PHP с помощью unserialize. Однако существует множество других форматов, например JSON или XML.


Возьмем, к примеру, эту распространенную проблему:

Как передать массив PHP в Javascript?

PHP и Javascript могут общаться только через строки. Вы можете "foo"очень легко передать строку в Javascript. Вы можете 1очень легко передать это число в Javascript. Вы можете передать булевы значения trueи falseлегко JavaScript. Но как передать этот массив в Javascript?

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

Ответ - сериализация . В случае PHP / Javascript JSON на самом деле является лучшим форматом сериализации:

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

Javascript может легко превратить это в фактический массив Javascript.

Это так же верно, как и представление той же структуры данных:

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

Но в значительной степени только PHP использует его, этот формат почти нигде не поддерживается.
Это очень распространено и хорошо поддерживается:

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

Есть много ситуаций, когда вам нужно передать сложные структуры данных в виде строк. Сериализация, представляющая произвольные структуры данных в виде строк, решает, как это сделать.


1
Ваше объяснение похоже на то, что я ожидал. не могли бы вы взглянуть на мою правку?
Istiaque Ahmed

1
каково объяснение этих a, i, s и т. д. в a: 3: {i: 1; s: 6: "elem 1"; i: 2; s: 6: "elem 2"; i: 3; s: 7: "elem 3";}? И если вы не возражаете, пример сериализации массива (может не иметь отношения к теме этого поста) для отправки его в js.
Istiaque Ahmed

2
Насколько мне известно, вряд ли можно найти формальную спецификацию этого формата, но вы можете догадаться, не так ли? i:1= целое число 1, s:6:"elem 1"= строка из 6 символов "elem 1" ... А какой пример вы просите, я думал, что привел?
deceze

«Но как передать этот массив в Javascript? Array ([1] => elem 1 [2] => elem 2 [3] => elem 3)» ... только точный фрагмент кода для него
Istiaque Ahmed

echo json_encode($array);Как именно вы его пройдете, зависит от обстоятельств. Не зацикливайтесь на этом.
deceze

27

Использование PHP serialize () unserialize ()

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

Что дает вам результат примерно так

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

снова, если вы хотите вернуть исходный массив, просто используйте функцию PHP unserialize ()

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

Я надеюсь, это поможет


7

Если вы хотите, чтобы ваше значение php сохранялось, вы должны превратить его в строковое значение, это то, что делает serialize () . А unserialize () делает обратное.


1
"сохраняемый" что это значит? Я просмотрел страницу, на которую вы ссылались. не могли бы вы показать пример на php и mysql (при необходимости)?
Istiaque Ahmed

2
@Istiaque Ahmed Например, когда вы хотите сохранить массив в файл на диске, вы не можете сохранить массив напрямую, а превратите его в сохраняемое значение, которое является строкой.
xdazz

но мы можем напрямую вставить переменную в базу данных без ее сериализации в php mysql. объяснение пожалуйста.
Istiaque Ahmed

9
«Мы можем вставить переменную в базу данных без ее сериализации» . Это верно только для основных типов данных (строки, целые числа, числа). Мы не можем вставлять массивы и объекты непосредственно в БД или файловую систему. Для этого serialize()и unserialize()созданы.
lorenzo-s

Вы берете некоторую информацию и работаете с ней в своем php-скрипте, готовом для хранения / отправки куда-нибудь. У вас есть возможность создать таблицу, которая точно соответствует ожидаемым данным, но это утомительно, вы по существу удваиваете свою рабочую нагрузку, потому что вам нужно писать код, который тоже соответствует, плюс изменения в базе данных требуют изменений в коде или наоборот. При сериализации вы можете просто создать таблицу с двумя столбцами с идентификатором int (10) и информационным BLOB. Serialise дает вам строку для вставки, а десериализация возвращает данные в исходное состояние. Есть случаи, когда это не так, документация php охватывает их.
Крис

7
<?php
$a= array("1","2","3");
print_r($a);
$b=serialize($a);
echo $b;
$c=unserialize($b);
print_r($c);

Запустите эту программу, она выведет вывод

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


здесь
a = размер массива
i = количество номеров массива
s = размер значений массива

вы можете использовать сериализацию для хранения массива данных в базе данных
и можете извлекать и не сериализовать данные для использования.


6

Большинство носителей могут хранить строку типы. Они не могут напрямую хранить структуру данных PHP, такую ​​как массив или объект, и не должны, так как это может связать носитель данных с PHP.

Вместо этого serialize()позволяет сохранить одну из этих структур в виде строки. Его можно десериализовать из строкового представления с помощьюunserialize() .

Если вы знакомы с json_encode()и json_decode()(и JSON в целом), концепция аналогична.


знаком с json. все еще неясность в php. отредактировал мой пост
Istiaque Ahmed

Зачем нужна сериализация, если есть json_encode? Пожалуйста, объясните, если знаете. Спасибо.
Евгений Афанасьев

1
@YevgeniyAfanasyev Может быть, вы не знаете о некоторых подмножествах данных. Но я думаю, что serialize()появился раньше JSON.
Alex

5

Пожалуйста! пожалуйста! пожалуйста! НЕ сериализуйте данные и не помещайте их в свою базу данных. Таким образом можно использовать сериализацию, но здесь не хватает реляционной базы данных и типов данных, присущих вашему ядру базы данных. Это делает данные в вашей базе данных непереносимыми, трудными для чтения и может усложнить запросы. Если вы хотите, чтобы ваше приложение было переносимым на другие языки, например, вы обнаружите, что хотите использовать Java для какой-то части вашего приложения, в которой имеет смысл использовать Java, сериализация станет головной болью. Вы всегда должны иметь возможность запрашивать и изменять данные в базе данных без использования стороннего посреднического инструмента для манипулирования данными, которые необходимо вставить.

это действительно затрудняет поддержку кода, кода с проблемами переносимости и данных, которые труднее перенести в другие системы RDMS, новую схему и т.д. поля, которые вы сериализовали.

Это не значит, что serialize () бесполезен. Это не ... Хорошим местом для использования может быть файл кеша, содержащий, например, результат операции с интенсивным использованием данных. Есть множество других ... Просто не злоупотребляйте сериализацией, потому что следующему парню, который придет, будет кошмар обслуживания или миграции.

Хороший пример serialize () и unserialize () может быть таким:

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

Десериализовать на странице

if($_GET['x']) {
   // unpack serialize and encoded URL
   $_POST = unserialize(base64_decode($_GET['x']));
}

2
Предоставленный код содержит несколько уязвимостей безопасности, люди, которые приходят и копируют и вставляют код, должны быть предупреждены.
Дэниел В.

Данный код - всего лишь пример того, как использовать функцию поиска и десериализации.
Авниш алок

2

Из http://php.net/manual/en/function.serialize.php :

Создает сохраняемое представление значения. Это полезно для хранения или передачи значений PHP без потери их типа и структуры.

По сути, он принимает массив или объект php и преобразует его в строку (которую вы затем можете передавать или хранить по своему усмотрению).

Unserialize используется для преобразования строки обратно в объект.


каково объяснение «сохраняемого представления»?
Istiaque Ahmed

Я видел, что сериализация используется только тогда, когда кто-то хочет взять массив php и сохранить его в базе данных. Вы можете сериализовать, сохранить вывод в стандартном строковом поле в своей базе данных, а затем захватить и десериализовать его, когда вы захотите использовать его снова.
MrGlass

1

По сути, когда вы сериализуете массивы или объекты, вы просто переводите их в допустимый строковый формат, чтобы их можно было легко хранить вне сценария php.

  1. Используйте сериализацию, чтобы сохранить состояние объекта в базе данных (давайте возьмем класс User в качестве примера). Затем десериализуйте данные, чтобы загрузить предыдущее состояние обратно в объект (методы не являются сериализаторами, вам необходимо включить класс объекта, чтобы иметь возможность использовать Это)
    • персонализация пользователя

Примечание для объекта вы должны использовать магические методы __sleep и __wakeup. __sleep вызывается serialize (). Метод сна вернет массив значений из объекта, который вы хотите сохранить.

__wakeup вызывается unserialize (). Метод пробуждения должен принимать несериализованные значения и инициализировать их в объекте.

Для передачи данных между php и js вы должны использовать json_encode, чтобы преобразовать массив php в допустимый формат json. Или наоборот - используйте JSON.parese () для преобразования выходных данных (строки) в действительный объект json. Вы бы хотели сделать это, чтобы использовать локальное хранилище. (автономный доступ к данным)


Зачем нужна сериализация, если есть json_encode? Пожалуйста, объясните, если знаете. Спасибо.
Евгений Афанасьев

1
Вы можете получить выгоду от возможности настраивать магический метод, который собирается при использовании сериализации и десериализации. Тем не менее, вы можете использовать Json_encode () и json_decode () гораздо дальше, и каждый объект может обрабатывать эти функции по-своему. Вот почему вы хотели бы их использовать.
DevWL 03

1
Это еще не все. См. Этот ответ для получения дополнительной информации stackoverflow.com/questions/804045/…
DevWL

1
json_encode работает быстрее (зависит от версии PHP, которую вы используете), json декодирует как stdClass, сериализованный объект десериализуется как фактический экземпляр класса, некоторая конфигурация должна быть сделана для JSON, чтобы сохранить кодировку UTF-8 без изменений, сериализация не меняет кодировку. Если вы хотите, чтобы данные кросс-платформенные использовали JSON, если вы работаете только с PHP, вы можете использовать магический метод __sleep и __wakeup для настройки сериализации.
DevWL 03

0

Да, я могу. Предположим, что нам нужно отслеживать вашу систему, значит, в вашей системе более одного администратора и субадмина. Все они могут вставлять, обновлять или редактировать любую информацию. Позже вам нужно знать, кто вносит это изменение. Для решения этой проблемы вам потребуется сериализация.

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

Я надеюсь, что это поможет вам.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.