Cách sử dụng php serialize () và unserialize ()


125

Vấn đề của tôi là rất cơ bản.

Tôi không tìm thấy bất kỳ ví dụ nào để đáp ứng nhu cầu của tôi về chính xác serialize()unserialize()nghĩa là gì trong php? Họ chỉ đưa ra một ví dụ - tuần tự hóa một mảng và hiển thị đầu ra ở định dạng không giải thích được. Thực sự khó hiểu khái niệm cơ bản thông qua biệt ngữ của họ.

BIÊN TẬP:

<?php

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

?>

đầu ra:

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

Tôi không thể hiểu đầu ra thứ hai. Bên cạnh đó, bất cứ ai có thể cho một ví dụ về tình huống mà tôi cần tuần tự hóa một mảng php trước khi sử dụng nó?


10
Trong trường hợp bạn vẫn tò mò về "đầu ra thứ cấp", nó khá đơn giản: a = array, 3 = of size ba phần tử trong {} 's. bên trong đó, bạn có i = số nguyên / chỉ số bằng 1, chuỗi len 6 bằng "elem 1", số nguyên bằng 2. v.v ... Nó khá rõ ràng khi bạn đọc nó như vậy. Bạn có thể tưởng tượng nhiều cấp độ của mảng / đối tượng có thể dễ dàng được chứa bên trong, tuy nhiên việc sửa đổi là rất thiếu khôn ngoan, bạn thực sự nên hủy số liệu hóa sửa đổi sau đó tuần tự hóa để đảm bảo tính nhất quán.
Grizly

2
@IstiaqueAhmed, Về việc "có ai có thể đưa ra ví dụ về tình huống mà tôi cần tuần tự hóa mảng php trước khi sử dụng nó không" , có một ví dụ như vậy tại stackoverflow.com/a/30436890/632951
Pacerier

@grizly nhờ người đàn ông, tôi đã tìm kiếm một câu trả lời như thế trong hai năm, tôi không biết làm thế nào để giải thích nó cũng không làm thế nào để liên kết các lý do cho việc sử dụng tính năng này, cảm ơn cho câu trả lời
isaacewing

Câu trả lời:


169

Một mảng hoặc đối tượng PHP hoặc cấu trúc dữ liệu phức tạp khác không thể được vận chuyển hoặc lưu trữ hoặc sử dụng bên ngoài một tập lệnh PHP đang chạy . Nếu bạn muốn duy trì một cấu trúc dữ liệu phức tạp như vậy ngoài một lần chạy tập lệnh, bạn cần phải tuần tự hóa nó. Điều đó chỉ có nghĩa là đặt cấu trúc vào một "mẫu số chung thấp hơn" có thể được xử lý bởi những thứ khác ngoài PHP, như cơ sở dữ liệu, tệp văn bản, ổ cắm. Hàm PHP tiêu chuẩn serializechỉ là một định dạng để thể hiện một thứ như vậy, nó tuần tự hóa cấu trúc dữ liệu thành một biểu diễn chuỗi duy nhất cho PHP và có thể được đảo ngược thành một đối tượng PHP bằng cách sử dụng unserialize. Tuy nhiên, có nhiều định dạng khác, như JSON hoặc XML.


Lấy ví dụ về vấn đề phổ biến này:

Làm cách nào để chuyển một mảng PHP sang Javascript?

PHP và Javascript chỉ có thể giao tiếp qua chuỗi. Bạn có thể chuyển chuỗi "foo"rất dễ dàng sang Javascript. Bạn có thể chuyển số 1rất dễ dàng sang Javascript. Bạn có thể chuyển các giá trị boolean truefalsedễ dàng sang Javascript. Nhưng làm thế nào để bạn chuyển mảng này sang Javascript?

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

Câu trả lời là tuần tự hóa . Trong trường hợp của PHP / Javascript, JSON thực sự là định dạng tuần tự hóa tốt hơn:

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

Javascript có thể dễ dàng đảo ngược điều này thành một mảng Javascript thực tế.

Mặc dù vậy, đây cũng là một biểu diễn hợp lệ của cùng một cấu trúc dữ liệu:

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

Nhưng hầu như chỉ có PHP sử dụng nó, có rất ít hỗ trợ cho định dạng này ở bất kỳ nơi nào khác.
Điều này là rất phổ biến và cũng được hỗ trợ:

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

Có nhiều trường hợp bạn cần chuyển các cấu trúc dữ liệu phức tạp xung quanh dưới dạng chuỗi. Tuần tự hóa, biểu diễn cấu trúc dữ liệu tùy ý dưới dạng chuỗi, giải quyết cách thực hiện điều này.


1
lời giải thích của bạn dường như đang tiếp cận với những gì tôi mong đợi. bạn có thể vui lòng xem bản chỉnh sửa của tôi được không?
Istiaque Ahmed

1
lời giải thích của những a, i, s vv trong a: 3: {i: 1; s: 6: "elem 1"; i: 2; s: 6: "elem 2"; i: 3; s: 7: "elem 3";}? Và nếu bạn không phiền, một ví dụ về việc tuần tự hóa mảng (có thể không liên quan đến chủ đề của bài đăng này) để gửi nó cho js.
Istiaque Ahmed

2
Theo như tôi biết thì hầu như không có thông số kỹ thuật chính thức về định dạng đó được tìm thấy, nhưng bạn có thể đoán được, phải không? i:1= số nguyên 1, s:6:"elem 1"= chuỗi có 6 ký tự "elem 1" ... Và ví dụ bạn đang yêu cầu, tôi nghĩ tôi đã đưa ra một ví dụ?
dối trá

"Nhưng làm cách nào để bạn chuyển mảng này sang Javascript? Mảng ([1] => elem 1 [2] => elem 2 [3] => elem 3)" ... chỉ là đoạn mã chính xác cho nó
Istiaque Ahmed

echo json_encode($array);Làm thế nào bạn vượt quachính xác tùy thuộc vào hoàn cảnh. Đừng quá bận tâm về điều đó.
dối trá

27

Sử dụng 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);

Điều này cung cấp cho bạn một kết quả như thế này

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

một lần nữa nếu bạn muốn lấy lại mảng ban đầu chỉ cần sử dụng hàm unserialize () của PHP

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

Hy vọng điều này có thể giúp cho bạn


7

Khi bạn muốn lưu trữ giá trị php của mình, bạn phải biến nó thành một giá trị chuỗi, đó là những gì serialize () thực hiện. Và unserialize () thực hiện điều ngược lại.


1
'đáng yêu' có nghĩa là gì? Tôi đã xem qua trang mà bạn đã giới thiệu. u có thể vui lòng hiển thị một ví dụ trong php và mysql (nếu cần thiết)?
Istiaque Ahmed 27/12/11

2
@Istiaque Ahmed Ví dụ: khi bạn muốn lưu một mảng vào một tệp trên đĩa, bạn không thể lưu mảng trực tiếp mà phải chuyển nó thành một giá trị lưu trữ và đó là một chuỗi.
xdazz

nhưng chúng ta có thể chèn trực tiếp một biến vào cơ sở dữ liệu mà không cần tuần tự hóa nó trong php mysql. làm ơn giải thích.
Istiaque Ahmed

9
"Chúng tôi có thể chèn một biến vào cơ sở dữ liệu mà không cần tuần tự hóa nó" . Điều này chỉ đúng với các kiểu dữ liệu cơ bản (chuỗi, số nguyên, số). Chúng ta không thể chèn trực tiếp mảng và đối tượng vào DB hoặc hệ thống tệp. Đó là những gì serialize()unserialize()được tạo ra để làm.
lorenzo-s

Bạn lấy một số thông tin và thực hiện một số thao tác với nó trong tập lệnh php của bạn đã sẵn sàng để lưu trữ / gửi nó đi đâu đó. Bạn có tùy chọn để tạo một bảng khớp chính xác với dữ liệu mong đợi, nhưng điều này thật tẻ nhạt, về cơ bản, bạn đang tăng gấp đôi khối lượng công việc của mình vì bạn phải viết mã khớp quá, cộng với những thay đổi trong cơ sở dữ liệu cần thay đổi mã hoặc ngược lại. Khi được tuần tự hóa, bạn có thể chỉ cần tạo một bảng với hai cột id int (10) và thông tin BLOB. Serialise cung cấp cho bạn một chuỗi để chèn và unserialize trả dữ liệu về trạng thái ban đầu. Có những trường hợp nó sẽ không, tài liệu php bao gồm những điều đó.
Chris

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

Chạy chương trình này tiếng vang đầu ra của nó

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


đây
a = kích thước mảng
i = đếm số mảng
s = kích thước giá trị mảng

bạn có thể sử dụng serialize để lưu trữ mảng dữ liệu trong cơ sở dữ liệu
và có thể truy xuất và UN-serialize dữ liệu để sử dụng.


6

Hầu hết các phương tiện lưu trữ có thể lưu trữ các loại chuỗi . Họ không thể lưu trữ trực tiếp cấu trúc dữ liệu PHP như một mảng hoặc đối tượng, và họ cũng không nên, vì điều đó sẽ kết hợp phương tiện lưu trữ dữ liệu với PHP.

Thay vào đó, serialize()cho phép bạn lưu trữ một trong những cấu trúc này dưới dạng chuỗi. Nó có thể được hủy tuần tự hóa khỏi biểu diễn chuỗi của nó với unserialize().

Nếu bạn đã quen thuộc với json_encode()json_decode()(và JSON nói chung), khái niệm này cũng tương tự.


quen với json. vẫn còn mờ mịt trong điều php. đã chỉnh sửa bài đăng của tôi
Istiaque Ahmed 27/12/11

Tại sao người ta cần tuần tự hóa nếu có mã json_encode? Xin vui lòng giải thích nếu bạn biết. Cảm ơn.
Yevgeniy Afanasyev

1
@YevgeniyAfanasyev Có thể bạn không thích một số tập dữ liệu con. Nhưng tôi nghĩ serialize()có trước JSON.
alex

5

Xin vui lòng! xin vui lòng! xin vui lòng! KHÔNG tuần tự hóa dữ liệu và đặt nó vào cơ sở dữ liệu của bạn. Serialize có thể được sử dụng theo cách đó, nhưng điều đó thiếu điểm của cơ sở dữ liệu quan hệ và các kiểu dữ liệu vốn có trong công cụ cơ sở dữ liệu của bạn. Làm điều này làm cho dữ liệu trong cơ sở dữ liệu của bạn không di động, khó đọc và có thể làm phức tạp các truy vấn. Nếu bạn muốn ứng dụng của mình có thể di động sang các ngôn ngữ khác, chẳng hạn như giả sử bạn thấy rằng bạn muốn sử dụng Java cho một số phần của ứng dụng mà việc sử dụng Java là hợp lý, thì việc tuần tự hóa sẽ trở thành một vấn đề khó khăn. Bạn sẽ luôn có thể truy vấn và sửa đổi dữ liệu trong cơ sở dữ liệu mà không cần sử dụng công cụ trung gian của bên thứ ba để thao tác với dữ liệu được chèn vào.

nó thực sự gây khó khăn cho việc duy trì mã, mã có vấn đề về tính di động và dữ liệu khó di chuyển hơn sang các hệ thống RDMS khác, lược đồ mới, v.v. Nó cũng có thêm một nhược điểm là làm cho việc tìm kiếm cơ sở dữ liệu của bạn trở nên lộn xộn dựa trên một trong các các trường mà bạn đã sắp xếp.

Điều đó không có nghĩa là serialize () là vô dụng. Nó không ... Một nơi tốt để sử dụng nó có thể là một tệp bộ đệm ẩn chứa kết quả của một thao tác sử dụng nhiều dữ liệu chẳng hạn. Có rất nhiều người khác ... Chỉ cần không lạm dụng serialize vì người đàn ông tiếp theo đi cùng sẽ có một cơn ác mộng bảo trì hoặc di chuyển.

Một ví dụ điển hình về serialize () và unserialize () có thể như sau:

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

Hủy số hóa trên trang

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

2
Mã được cung cấp có chứa một số lỗ hổng bảo mật, những người đến và sao chép mã dán nên được cảnh báo.
Daniel W.

Mã đã cho chỉ là một ví dụ về cách sử dụng hàm searilize và unserialize.
Avnish alok

2

Từ http://php.net/manual/en/ Chức năng.serialize.php :

Tạo một biểu diễn lưu trữ của một giá trị. Điều này rất hữu ích để lưu trữ hoặc chuyển các giá trị PHP xung quanh mà không làm mất kiểu và cấu trúc của chúng.

Về cơ bản, nó lấy một mảng hoặc đối tượng php và chuyển đổi nó thành một chuỗi (sau đó bạn có thể truyền hoặc lưu trữ khi bạn thấy phù hợp).

Unserialize được sử dụng để chuyển đổi chuỗi trở lại một đối tượng.


lời giải thích của 'đại diện đáng yêu' là gì?
Istiaque Ahmed

Tôi chỉ thấy serialize được sử dụng khi ai đó muốn lấy một mảng php và lưu trữ nó trong cơ sở dữ liệu. Bạn có thể tuần tự hóa, lưu trữ kết quả đầu ra trong trường chuỗi tiêu chuẩn trong cơ sở dữ liệu của mình, sau đó lấy và hủy số hóa nó khi bạn muốn sử dụng lại.
MrGlass 27/12/11

1

Về cơ bản, khi bạn tuần tự hóa các mảng hoặc đối tượng, bạn chỉ cần chuyển nó sang định dạng chuỗi hợp lệ để bạn có thể dễ dàng lưu trữ chúng bên ngoài tập lệnh php.

  1. Sử dụng serialize để lưu trạng thái của một đối tượng trong cơ sở dữ liệu (hãy lấy lớp Người dùng làm ví dụ) Tiếp theo hủy số hóa dữ liệu để tải trạng thái trước đó trở lại đối tượng (các phương thức không phải là serializer mà bạn cần bao gồm lớp đối tượng để có thể sử dụng nó)
    • cá nhân hóa người dùng

Lưu ý đối với đối tượng bạn nên sử dụng phương thức magic __sleep và __wakeup. __sleep được gọi bởi serialize (). Phương thức sleep sẽ trả về một mảng các giá trị từ đối tượng mà bạn muốn duy trì.

__wakeup được gọi bởi unserialize (). Một phương thức đánh thức phải lấy các giá trị chưa được số hóa và khởi tạo chúng trong đối tượng.

Để chuyển dữ liệu giữa php và js, bạn sẽ sử dụng json_encode để chuyển mảng php sang định dạng json hợp lệ. Hoặc theo cách khác - sử dụng JSON.parese () để chuyển đổi dữ liệu đầu ra (chuỗi) thành đối tượng json hợp lệ. Bạn sẽ muốn làm điều đó để sử dụng bộ nhớ cục bộ. (truy cập dữ liệu ngoại tuyến)


Tại sao người ta cần tuần tự hóa nếu có mã json_encode? Xin vui lòng giải thích nếu bạn biết. Cảm ơn.
Yevgeniy Afanasyev

1
Bạn có thể hưởng lợi từ việc có thể tùy chỉnh phương pháp ma thuật được cuộn lại khi sử dụng serialize và unserialise. Điều đó nói rằng bạn có thể sử dụng Json_encode () và json_decode () nhiều hơn nữa và mỗi đối tượng có thể xử lý các chức năng này theo cách riêng của nó. Đây là lý do tại sao bạn muốn sử dụng chúng.
DevWL

1
Còn nhiều hơn thế nữa. Xem câu trả lời này để biết thêm thông tin stackoverflow.com/questions/804045/…
DevWL

1
json_encode nhanh hơn (tùy thuộc vào phiên bản PHP mà bạn đang sử dụng), json giải mã dưới dạng stdClass, đối tượng serized unserialize như phiên bản Class thực tế, Một số cấu hình tôi phải thực hiện với JSON để giữ nguyên mã hóa UTF-8 không thay đổi, serialize không thay đổi mã hóa. Nếu bạn muốn tạo dữ liệu đa nền tảng bằng cách sử dụng JSON, Nếu bạn chỉ làm việc với PHP, bạn có thể sử dụng phương thức ma thuật __sleep và __wakeup để tùy chỉnh tuần tự hóa.
DevWL

0

Vâng tôi có thể. Giả sử chúng tôi cần theo dõi hệ thống của bạn nghĩa là Trong hệ thống của bạn có nhiều quản trị viên và subadmin, Tất cả những người này có thể chèn hoặc cập nhật hoặc chỉnh sửa bất kỳ thông tin nào. Sau đó bạn cần biết ai thực hiện thay đổi này. Để giải quyết vấn đề này, bạn cần tuần tự hóa.

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

Tôi hy vọng điều này sẽ giúp bạn.


-1
preg_match_all('/\".*?\"/i', $string, $matches);
foreach ($matches[0] as $i => $match) $matches[$i] = trim($match, '"');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.