Jak używać php serialize () i unserialize ()

125

Mój problem jest bardzo podstawowy.

Nie znalazłem żadnego przykładu, który spełniałby moje potrzeby, co dokładnie serialize()i co unserialize()oznacza w php? Podają tylko przykład - serializują tablicę i pokazują dane wyjściowe w niewyjaśnionym formacie. Naprawdę trudno jest zrozumieć podstawową koncepcję dotyczącą ich żargonu.

EDYTOWAĆ:

<?php

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

?>

wynik:

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

Nie rozumiem drugiego wyjścia. Poza tym, czy ktoś może podać przykład sytuacji, w której muszę serializować tablicę php przed jej użyciem?

Istiaque Ahmed
źródło
10
Jeśli nadal byłeś ciekawy „drugorzędnego wyjścia”, jest to dość proste: a = tablica, 3 = o rozmiarze trzech elementów w {}. wewnątrz tego masz i = liczba całkowita / indeks równa 1, ciąg len 6 równy "elem 1", liczba całkowita równa 2 .. itd. itd. Jest całkiem jasne, kiedy to czytasz w ten sposób. Możesz sobie wyobrazić, że wiele poziomów tablic / obiektów jest łatwo zawartych, jednak modyfikacja jest bardzo nierozsądna, powinieneś naprawdę odserializować, zmodyfikować, a następnie serializować, aby zapewnić spójność.
Grizly
2
@IstiaqueAhmed, Jeśli chodzi o „czy ktoś może podać przykład sytuacji, w której muszę serializować tablicę php przed jej użyciem” , taki przykład znajduje się na stackoverflow.com/a/30436890/632951
Pacerier
@grizly thanks man, od dwóch lat szukałem takiej odpowiedzi, nie wiedziałem jak to wytłumaczyć ani jak skojarzyć powód użycia tej funkcji, dzięki za odpowiedź
isaacewing

Odpowiedzi:

169

Tablica lub obiekt PHP lub inna złożona struktura danych nie może być transportowana, przechowywana ani używana w inny sposób poza uruchomionym skryptem PHP . Jeśli chcesz zachować tak złożoną strukturę danych poza jednym uruchomieniem skryptu, musisz ją serializować . Oznacza to po prostu umieszczenie struktury w „niższym wspólnym mianowniku”, który może być obsługiwany przez elementy inne niż PHP, takie jak bazy danych, pliki tekstowe, gniazda. Standardowa funkcja PHP serializejest po prostu formatem służącym do wyrażania takich rzeczy, serializuje strukturę danych do postaci łańcucha, która jest unikalna dla PHP i może zostać odwrócona do obiektu PHP za pomocą unserialize. Istnieje jednak wiele innych formatów, takich jak JSON lub XML.


Weźmy na przykład ten powszechny problem:

Jak przekazać tablicę PHP do JavaScript?

PHP i Javascript mogą komunikować się tylko za pomocą łańcuchów. Możesz "foo"bardzo łatwo przekazać ciąg znaków do Javascript. Możesz 1bardzo łatwo przekazać ten numer do Javascript. Można przekazać wartości logiczne truei falsełatwe do Javascript. Ale jak przekazać tę tablicę do Javascript?

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

Odpowiedzią jest serializacja . W przypadku PHP / Javascript JSON jest faktycznie lepszym formatem serializacji:

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

Javascript może łatwo odwrócić to do rzeczywistej tablicy Javascript.

Jest to jednak równie ważna reprezentacja tej samej struktury danych:

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

Ale prawie tylko PHP go używa, nigdzie indziej nie ma wsparcia dla tego formatu.
Jest to jednak bardzo powszechne i dobrze obsługiwane:

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

Istnieje wiele sytuacji, w których trzeba przekazywać złożone struktury danych w postaci łańcuchów. Serializacja, reprezentująca dowolne struktury danych jako ciągi, rozwiązuje, jak to zrobić.

zamrozić
źródło
1
Twoje wyjaśnienie wydaje się zbliżać do tego, czego się spodziewałem. czy możesz rzucić okiem na moją zmianę?
Istiaque Ahmed
1
jakie jest wyjaśnienie tych a, i, s itp. w a: 3: {i: 1; s: 6: "elem 1"; i: 2; s: 6: "elem 2"; i: 3; s: 7: "elem 3";}? A jeśli nie masz nic przeciwko, przykład serializacji tablicy (może nie mieć związku z tematem tego postu), aby wysłać ją do js.
Istiaque Ahmed
2
O ile mi wiadomo, trudno znaleźć formalną specyfikację tego formatu, ale możesz zgadywać, prawda? i:1= liczba całkowita 1, s:6:"elem 1"= ciąg z 6 znakami „elem 1” ... A o jaki przykład prosisz, myślałem, że podałem jeden?
deceze
„Ale jak przekazać tę tablicę do Javascript? Array ([1] => elem 1 [2] => elem 2 [3] => elem 3)” ... tylko dokładny fragment kodu
Istiaque Ahmed
echo json_encode($array);To , jak dokładnie to zdasz , zależy od okoliczności. Nie przejmuj się tym.
deceze
27

Użycie serialize () unserialize () 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);

Co daje wynik podobny do tego

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

ponownie, jeśli chcesz odzyskać oryginalną tablicę, użyj funkcji PHP unserialize ()

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

Mam nadzieję, że to pomoże

tipico
źródło
7

Jeśli chcesz, aby wartość php była przechowywana, musisz zmienić ją na wartość ciągu, tak właśnie robi serialize () . I unserialize () robi coś odwrotnego.

xdazz
źródło
1
„do przechowywania”, co to znaczy? Przejrzałem wskazaną przez Ciebie stronę. czy możesz pokazać przykład w php i mysql (jeśli to konieczne)?
Istiaque Ahmed
2
@Istiaque Ahmed Na przykład, jeśli chcesz zapisać tablicę w pliku na dysku, nie możesz bezpośrednio zapisać tablicy, ale przekształcić ją w wartość, którą można przechowywać, a jest to ciąg.
xdazz
ale możemy bezpośrednio wstawić zmienną do bazy danych bez serializacji w php mysql. wyjaśnienie proszę.
Istiaque Ahmed
9
„Możemy wstawić zmienną do bazy danych bez jej serializacji” . Dotyczy to tylko podstawowych typów danych (ciągi znaków, liczby całkowite, liczby). Nie możemy wstawiać tablic i obiektów bezpośrednio do bazy danych lub systemu plików. Do tego serialize()i unserialize()są stworzone.
lorenzo-s,
Bierzesz trochę informacji i wykonujesz z nimi pracę w swoim skrypcie php, gotowym do przechowywania / wysyłania ich gdzieś. Masz możliwość utworzenia tabeli, która dokładnie odpowiada oczekiwanym danym, ale jest to żmudne, ponieważ zasadniczo podwajasz obciążenie pracą, ponieważ musisz pisać również pasujący kod, a zmiany w bazie danych wymagają zmian w kodzie lub odwrotnie. Po serializacji można po prostu utworzyć tabelę z dwiema kolumnami o identyfikatorze int (10) i informacją BLOB. Serialise daje ciąg do wstawienia, a odserializacja przywraca dane do ich pierwotnego stanu. Są przypadki, w których to się nie uda, dokumenty php obejmują je.
Chris
7
<?php
$a= array("1","2","3");
print_r($a);
$b=serialize($a);
echo $b;
$c=unserialize($b);
print_r($c);

Uruchom ten program, aby wyświetlić wynik

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


tutaj
a = rozmiar tablicy
i = liczba numerów tablicy
s = rozmiar wartości tablicy

możesz użyć serializacji do przechowywania tablicy danych w bazie danych
i możesz pobierać i UN-serializować dane do użycia.

Manikandan
źródło
6

Większość nośników danych może przechowywać typy ciągów . Nie mogą bezpośrednio przechowywać struktury danych PHP, takiej jak tablica lub obiekt, i nie powinny, ponieważ spowodowałoby to połączenie nośnika danych z PHP.

Zamiast tego serialize()umożliwia przechowywanie jednej z tych struktur jako ciągu. Można go zdeserializować z reprezentacji ciągu za pomocą unserialize().

Jeśli znasz json_encode()i json_decode()(i ogólnie JSON), koncepcja jest podobna.

Alex
źródło
zaznajomiony z json. wciąż niejasność w php. zredagował mój post
Istiaque Ahmed
Dlaczego trzeba serializować, jeśli istnieje json_encode? Proszę wyjaśnij, jeśli wiesz. Dzięki.
Yevgeniy Afanasyev
1
@YevgeniyAfanasyev Może nie dla niektórych podzbiorów danych. Ale myślę, że serialize()poprzedza JSON.
alex
5

Proszę! Proszę! Proszę! NIE serializuj danych i nie umieszczaj ich w swojej bazie danych. Serialize może być używany w ten sposób, ale to oznacza brak sensu relacyjnej bazy danych i typów danych właściwych dla twojego silnika bazy danych. W ten sposób dane w Twojej bazie danych są nieprzenośne, trudne do odczytania i może skomplikować zapytania. Jeśli chcesz, aby Twoja aplikacja była przenośna do innych języków, na przykład, powiedzmy, że odkryjesz, że chcesz używać Javy w jakiejś części aplikacji, w której warto używać Javy, serializacja stanie się bólem pośladków. Zawsze powinieneś mieć możliwość przeszukiwania i modyfikowania danych w bazie danych bez korzystania z narzędzia pośredniczącego strony trzeciej do manipulowania danymi, które mają być wstawione.

naprawdę utrudnia utrzymanie kodu, kodu z problemami z przenośnością i danych, które są trudniejsze do migracji do innych systemów RDMS, nowego schematu itp. Ma również tę dodatkową wadę, że utrudnia przeszukiwanie bazy danych na podstawie jednego z pola, które zserializowałeś.

Nie znaczy to, że serialize () jest bezużyteczny. To nie jest ... Dobrym miejscem do użycia może być na przykład plik pamięci podręcznej zawierający wynik operacji intensywnie wykorzystującej dane. Jest mnóstwo innych ... Po prostu nie nadużywaj serializacji, ponieważ następny facet, który przyjdzie, będzie miał koszmar związany z konserwacją lub migracją.

Dobry przykład serialize () i unserialize () może wyglądać tak:

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

Usuń numer seryjny na stronie

if($_GET['x']) {
   // unpack serialize and encoded URL
   $_POST = unserialize(base64_decode($_GET['x']));
}
Avnish alok
źródło
2
Dostarczony kod zawiera kilka luk w zabezpieczeniach, należy ostrzec ludzi przychodzących i kopiujących wklejany kod.
Daniel W.
Podany kod jest tylko przykładem wykorzystania funkcji Searilize i unserialize.
Avnish alok
2

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

Generuje możliwą do przechowywania reprezentację wartości. Jest to przydatne do przechowywania lub przekazywania wartości PHP bez utraty ich typu i struktury.

Zasadniczo pobiera tablicę lub obiekt php i konwertuje ją na łańcuch (który można następnie przesłać lub przechowywać według własnego uznania).

Unserialize służy do konwersji ciągu z powrotem do obiektu.

MrGlass
źródło
jakie jest wyjaśnienie „reprezentacji, którą można przechowywać”?
Istiaque Ahmed
Widziałem serializację używaną tylko wtedy, gdy ktoś chciał pobrać tablicę php i zapisać ją w bazie danych. Możesz serializować, przechowywać dane wyjściowe w standardowym polu ciągu w bazie danych, a następnie pobrać i cofnąć szeregowanie, gdy chcesz użyć go ponownie.
MrGlass,
1

Zasadniczo, kiedy serializujesz tablice lub obiekty, po prostu zmieniasz je na prawidłowy format ciągu, abyś mógł łatwo przechowywać je poza skryptem php.

  1. Użyj serializacji, aby zapisać stan obiektu w bazie danych (weźmy klasę User jako przykład) Następnie usuń szeregowanie danych, aby załadować poprzedni stan z powrotem do obiektu (metody nie są serializatorami, musisz dołączyć klasę obiektu, aby móc używać to)
    • personalizacja użytkownika

Uwaga dla obiektu powinieneś używać magicznych metod __sleep i __wakeup. __sleep jest wywoływana przez serialize (). Metoda uśpienia zwróci tablicę wartości z obiektu, który chcesz zachować.

Funkcja __wakeup jest wywoływana przez unserialize (). Metoda wakeup powinna pobierać nieserializowane wartości i inicjować je w nich w obiekcie.

Do przekazywania danych między php i js należy użyć json_encode, aby zmienić tablicę php na prawidłowy format json. Lub odwrotnie - użyj JSON.parese (), aby przekonwertować dane wyjściowe (ciąg znaków) na prawidłowy obiekt json. Chciałbyś to zrobić, aby skorzystać z lokalnej pamięci. (dostęp do danych offline)

DevWL
źródło
Dlaczego trzeba serializować, jeśli istnieje json_encode? Proszę wyjaśnij, jeśli wiesz. Dzięki.
Yevgeniy Afanasyev
1
Możesz skorzystać z możliwości dostosowania magicznych metod, które są zbierane podczas korzystania z serializacji i nieserializacji. To powiedziawszy, możesz zabrać Json_encode () i json_decode () znacznie dalej, a każdy obiekt może obsługiwać te funkcje w swój unikalny sposób. Dlatego chciałbyś ich używać.
DevWL
1
To nie wszystko. Zobacz tę odpowiedź, aby uzyskać więcej informacji stackoverflow.com/questions/804045/…
DevWL
1
json_encode jest szybszy (w zależności od używanej wersji PHP), json dekoduje jako stdClass, zserializowany obiekt unserialize jako rzeczywista instancja klasy, Niektóre konfiguracje muszą zostać wykonane w JSON, aby zachować niezmienione kodowanie UTF-8, serializacja nie zmienia kodowania. Jeśli chcesz, aby dane między platformami korzystały z JSON, jeśli pracujesz tylko w PHP, możesz użyć magicznych metod __sleep i __wakeup, aby dostosować serializację.
DevWL
0

Tak, mogę. Załóżmy, że musimy śledzić twój system oznacza, że ​​Twój system ma więcej niż jednego administratora i subadmina, wszyscy z nich mogą wstawiać, aktualizować lub edytować dowolne informacje. Później musisz wiedzieć, kto wprowadza tę zmianę. Aby rozwiązać ten problem, potrzebujesz serializacji.

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

Mam nadzieję, że to Ci pomoże.


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