Як використовувати php serialize () та unserialia ()


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 = три елементи розміру всередині {} 's. всередині цього у вас i = ціле число / індекс, що дорівнює 1, рядок len 6 дорівнює "elem 1", ціле число дорівнює 2 .. і т. д. і т.д. Ви можете уявити, що декілька рівнів масивів / об'єктів легко містяться всередині, проте модифікація дуже нерозумна, вам слід справді несеріалізувати модифікацію, а потім серіалізувати, щоб забезпечити узгодженість.
Grizly

2
@IstiaqueAhmed, Що стосується «може хто - небудь привести приклад ситуації , що мені потрібно серіалізовать масив PHP , перш ніж використовувати його» , є такий приклад в stackoverflow.com/a/30436890/632951
Pacerier

@ grizly спасибі людино, я шукав таку відповідь два роки, я не знав, як це пояснити, ні як пов’язати причину використання цієї функції, дякую за відповідь
isaacewing

Відповіді:


169

Масив 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
Ур пояснення, здається, наближається до того, що я очікував. Ви можете, будь ласка, подивитись на мою редакцію?
Істіаке Ахмед

1
яке пояснення цих a, i, s тощо у: 3: {i: 1; s: 6: "elem 1"; i: 2; s: 6: "elem 2"; i: 3; s: 7: "елем 3";}? І якщо ви не заперечуєте, приклад серіалізації масиву (можливо, не стосується теми цієї публікації), щоб надіслати його до js.
Істіаке Ахмед

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

"Але як ви передаєте цей масив Javascript? Array ([1] => elem 1 [2] => elem 2 [3] => elem 3)" ... просто точний фрагмент коду для нього
Istiaque Ahmed

echo json_encode($array);Як саме ви пройдете це, залежить від обставин. Не зациклюйтеся на цьому.
деге

27

PHP серіалізувати () несеріалізувати () використання

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 (якщо потрібно)?
Істіак Ахмед

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

але ми можемо безпосередньо вставити змінну в базу даних, не серіалізуючи її в php mysql. пояснення будь ласка.
Істіаке Ахмед

9
"Ми можемо вставити змінну в базу даних, не серіалізуючи її" . Це справедливо лише для основних типів даних (рядки, цілі числа, числа). Ми не можемо вставляти масиви та об'єкти безпосередньо в БД або файлову систему. Саме для цього serialize()і unserialize()створені.
lorenzo-s

Ви берете деяку інформацію і виконайте певну роботу з нею у вашому php-скрипті, готовому зберігати / відправляти її кудись. У вас є можливість створити таблицю, яка б точно відповідала очікуваним даним, але це нудно, ви по суті подвоюєте ваше робоче навантаження, оскільки вам також потрібно написати код, який відповідає, плюс зміни в базі даних потребують змін у коді або навпаки. При серіалізації ви можете просто створити таблицю з двома стовпцями id 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 = розмір значень масиву

ви можете використовувати серіалізацію для зберігання масиву даних у базі даних
і можете отримувати та UN-серіалізувати дані для використання.


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, нові схеми тощо. Це також має додатковий недолік, оскільки він стає безладним для пошуку вашої бази даних на основі однієї з поля, які ви серіалізували.

Це не означає, що серіалізувати () марно. Це не ... Хорошим місцем для його використання може бути кеш-файл, який містить результат, наприклад, інтенсивної роботи з даними. Є багато інших ... Просто не зловживайте серіалізацією, тому що наступний хлопець, який приїде разом, матиме кошмар на обслуговування або міграцію.

Хороший приклад серіалізації () та несеріалізації () може бути таким:

$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 використовується для перетворення рядка назад в об'єкт.


яке пояснення "зберігається в представництві"?
Істіаке Ахмед

Ive бачив серіалізацію, що використовується, коли хтось захотів взяти масив php і зберегти його в базі даних. Ви можете серіалізувати, зберігати результат у стандартному рядковому полі у вашій базі даних, а потім захопити та несеріалізувати його, коли ви хочете знову використовувати його.
MrGlass

1

В основному, коли ви серіалізуєте масиви або об’єкти, ви просто перетворите їх у дійсний формат рядка, щоб ви могли легко зберігати їх поза скриптом php.

  1. Використовуйте серіалізацію для збереження стану об'єкта в базі даних (давайте взяти клас користувача, як приклад) Далі сканіруйте дані, щоб завантажити попередній стан назад на об'єкт (методи не є серіалізатором. Вам потрібно включити клас об'єктів, щоб мати можливість використовувати це)
    • персоналізація користувача

Зауважте, що для об'єкта слід використовувати магічні методи __sleep та __wakeup. __sleep викликається serialize (). Метод сну поверне масив значень з об'єкта, який потрібно зберегти.

__ пробудження викликається unserialize (). Метод пробудження повинен приймати несеріалізовані значення та ініціалізувати їх у них в об'єкті.

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


Навіщо потрібно серіалізувати, якщо є json_encode? Будь-ласка, поясніть, якщо знаєте. Дякую.
Євген Афанасьєв

1
Ви можете скористатися тим, що зможете налаштувати магічний метод, який застосовується під час використання серіалізації та несеріалізації. Це означає, що ви можете брати Json_encode () та json_decode () набагато далі, і кожен об'єкт може обробляти цей функтинос унікальним чином. Ось чому ви б хотіли ними користуватися.
DevWL

1
Тут є набагато більше. Дивіться цей відповідь для отримання додаткової інформації stackoverflow.com/questions/804045 / ...
DevWL

1
json_encode швидший (залежить від версії PHP, яку ви використовуєте), json декодує як stdClass, серіалізований об’єкт несеріалізується як фактичний екземпляр класу, деяка конфігурація, яку я зробила в JSON, щоб зберегти кодування UTF-8 без змін, серіалізація не змінює кодування. Якщо ви хочете, щоб перехресна платформа даних використовувала JSON, якщо ви працюєте лише в PHP, ви можете використовувати магічний метод __sleep та __wakeup для налаштування серіалізації.
DevWL

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)

Я сподіваюся, що це вам допоможе.


-1
preg_match_all('/\".*?\"/i', $string, $matches);
foreach ($matches[0] as $i => $match) $matches[$i] = trim($match, '"');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.