วิธีใช้ 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 array ก่อนใช้งานได้หรือไม่?


10
ในกรณีที่คุณยังสงสัยเกี่ยวกับ "เอาต์พุตรอง" มันค่อนข้างง่าย: a = array, 3 = จากขนาดสามองค์ประกอบภายใน {} ภายในนั้นคุณมี i = จำนวนเต็ม / ดัชนีเท่ากับ 1 สตริงของ len 6 เท่ากับ "elem 1" จำนวนเต็มเท่ากับ 2 .. ฯลฯ ฯลฯ มันค่อนข้างชัดเจนเมื่อคุณอ่านแบบนั้น คุณสามารถจินตนาการถึงอาร์เรย์ / ออบเจ็กต์หลายระดับที่บรรจุอยู่ภายในได้อย่างง่ายดายอย่างไรก็ตามการปรับเปลี่ยนนั้นไม่ฉลาดมากคุณควรยกเลิกการปรับเปลี่ยนจากนั้นจึงทำให้เป็นอนุกรมเพื่อให้แน่ใจว่าสอดคล้องกัน
Grizly

2
@IstiaqueAhmed เกี่ยวกับ"ทุกคนสามารถยกตัวอย่างสถานการณ์ที่ฉันต้องทำให้อนุกรม php อาร์เรย์ก่อนที่จะใช้"มีตัวอย่างดังกล่าวที่stackoverflow.com/a/30436890/632951
Pacerier

@grizly ขอบคุณมากฉันหาคำตอบแบบนั้นมาสองปีแล้วไม่รู้จะอธิบายยังไงหรือจะเชื่อมโยงเหตุผลในการใช้ฟีเจอร์นั้นยัง
ไง

คำตอบ:


169

อาร์เรย์ PHP หรืออ็อบเจ็กต์หรือโครงสร้างข้อมูลที่ซับซ้อนอื่น ๆไม่สามารถขนส่งหรือจัดเก็บหรือใช้นอกเหนือจากสคริปต์ PHP ที่กำลังทำงานอยู่ หากคุณต้องการที่จะยังคงมีอยู่เช่นโครงสร้างข้อมูลที่ซับซ้อนเกินกว่าการทำงานครั้งเดียวของสคริปต์คุณจะต้องเป็นอันดับมัน นั่นหมายถึงการใส่โครงสร้างให้เป็น "ตัวหารร่วมที่ต่ำกว่า" ซึ่งสามารถจัดการได้ด้วยสิ่งอื่นที่ไม่ใช่ PHP เช่นฐานข้อมูลไฟล์ข้อความซ็อกเก็ต ฟังก์ชั่น PHP มาตรฐานserializeเป็นเพียงรูปแบบที่จะแสดงสิ่งนั้นมัน serializes โครงสร้างข้อมูลที่เป็นตัวแทนสตริงที่ไม่ซ้ำกับ 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" ... แล้วคุณจะขอตัวอย่างอะไรฉันคิดว่าฉันให้ไป
หลอกลวง

"แต่คุณจะส่งอาร์เรย์นี้ไปยัง Javascript ได้อย่างไร Array ([1] => elem 1 [2] => elem 2 [3] => elem 3)" ... เพียงแค่ข้อมูลโค้ดเท่านั้น
Istiaque Ahmed

echo json_encode($array);วิธีว่าคุณจะผ่านมันขึ้นอยู่กับสถานการณ์ อย่าเพิ่งวางสายเกินไป
หลอกลวง

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 คุ้มค่าที่สามารถจัดเก็บของคุณคุณต้องเปิดให้เป็นค่าสตริงว่าเป็นสิ่งที่เป็นอันดับ ()ไม่ และUnserialize ()ทำสิ่งที่ตรงกันข้าม


1
'storable' หมายความว่าอย่างไร? ฉันได้ดูหน้าเว็บที่คุณอ้างถึง คุณช่วยแสดงตัวอย่างใน php และ mysql (ถ้าจำเป็น) ได้ไหม
Istiaque Ahmed

2
@Istiaque Ahmed ตัวอย่างเช่นเมื่อคุณต้องการจัดเก็บอาร์เรย์ลงในไฟล์บนดิสก์คุณไม่สามารถบันทึกอาร์เรย์ได้โดยตรง แต่เปลี่ยนเป็นค่าที่เก็บได้และนั่นคือสตริง
xdazz

แต่เราสามารถแทรกตัวแปรลงในฐานข้อมูลได้โดยตรงโดยไม่ต้องทำให้เป็นอนุกรมใน php mysql กรุณาอธิบาย
Istiaque Ahmed

9
"เราสามารถแทรกตัวแปรลงในฐานข้อมูลโดยไม่ต้อง serializing มัน" นี่เป็นจริงสำหรับชนิดข้อมูลพื้นฐานเท่านั้น (สตริงจำนวนเต็มตัวเลข) เราไม่สามารถแทรกอาร์เรย์และวัตถุโดยตรงเข้าไปในฐานข้อมูลหรือระบบแฟ้ม นั่นคือสิ่งที่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";}


ที่นี่
= ขนาดของอาร์เรย์
i = จำนวนอาร์เรย์
s = ขนาดของค่าอาร์เรย์

คุณสามารถใช้ serialize เพื่อจัดเก็บอาร์เรย์ของข้อมูลในฐานข้อมูล
และสามารถดึงและ UN-serialize ข้อมูลเพื่อใช้


6

สื่อบันทึกข้อมูลส่วนใหญ่สามารถจัดเก็บประเภทสตริงได้ พวกเขาไม่สามารถจัดเก็บโครงสร้างข้อมูล PHP โดยตรงเช่นอาร์เรย์หรือวัตถุได้และไม่ควรทำเช่นนั้นเนื่องจากจะจับคู่สื่อจัดเก็บข้อมูลกับ PHP

แต่serialize()ช่วยให้คุณเก็บหนึ่ง structs เหล่านี้เป็นสตริง สามารถยกเลิกการทำให้เป็นอนุกรมจากการแสดงสตริงด้วยunserialize().

หากคุณมีความคุ้นเคยกับjson_encode()และjson_decode()(และ JSON ทั่วไป) เป็นแนวคิดที่คล้ายกัน


คุ้นเคยกับ json ยังคงสับสนในสิ่ง php แก้ไขโพสต์ของฉัน
Istiaque Ahmed

ทำไมต้องทำให้เป็นอนุกรมหากมี json_encode กรุณาอธิบายหากคุณทราบ ขอบคุณ
Yevgeniy Afanasyev

1
@YevgeniyAfanasyev บางทีคุณอาจจะไม่ใช้ข้อมูลบางส่วน แต่ฉันคิดว่าserialize()มาก่อน JSON
alex

5

กรุณา! กรุณา! กรุณา! อย่าจัดลำดับข้อมูลและวางลงในฐานข้อมูลของคุณ Serialize สามารถใช้ในลักษณะนั้นได้ แต่ไม่มีจุดของฐานข้อมูลเชิงสัมพันธ์และประเภทข้อมูลที่มีอยู่ในเครื่องมือฐานข้อมูลของคุณ การทำเช่นนี้ทำให้ข้อมูลในฐานข้อมูลของคุณไม่พกพาอ่านยากและอาจทำให้การสืบค้นซับซ้อน หากคุณต้องการให้แอปพลิเคชันของคุณสามารถพกพาไปยังภาษาอื่น ๆ ได้เช่นสมมติว่าคุณพบว่าคุณต้องการใช้ 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
รหัสที่ให้มามีช่องโหว่ด้านความปลอดภัยหลายประการควรแจ้งเตือนผู้ที่มาและคัดลอกวางโค้ด
Daniel W.

โค้ดที่ระบุเป็นเพียงตัวอย่างของวิธีการใช้ฟังก์ชันค้นหาและยกเลิกการระบุข้อมูล
Avnish alok

2

จากhttp://php.net/manual/en/function.serialize.php :

สร้างการแสดงค่าที่เก็บได้ สิ่งนี้มีประโยชน์สำหรับการจัดเก็บหรือส่งผ่านค่า PHP โดยไม่สูญเสียประเภทและโครงสร้าง

โดยพื้นฐานแล้วจะใช้อาร์เรย์ php หรือวัตถุและแปลงเป็นสตริง (ซึ่งคุณสามารถส่งหรือจัดเก็บได้ตามที่เห็นสมควร)

Unserialize ใช้เพื่อแปลงสตริงกลับเป็นอ็อบเจกต์


คำอธิบายของ 'การเป็นตัวแทนที่เก็บได้' คืออะไร?
Istiaque Ahmed

ive เห็นเฉพาะ serialize ที่ใช้เมื่อมีคนต้องการใช้ php array และเก็บไว้ในฐานข้อมูล คุณสามารถซีเรียลไลซ์จัดเก็บเอาต์พุตในฟิลด์สตริงมาตรฐานในฐานข้อมูลของคุณจากนั้นคว้าและยกเลิกการเข้ารหัสเมื่อคุณต้องการใช้อีกครั้ง
MrGlass

1

โดยพื้นฐานแล้วเมื่อคุณจัดลำดับอาร์เรย์หรือวัตถุคุณเพียงแค่เปลี่ยนเป็นรูปแบบสตริงที่ถูกต้องเพื่อให้คุณสามารถจัดเก็บไว้นอกสคริปต์ php ได้อย่างง่ายดาย

  1. ใช้ซีเรียลไลซ์เพื่อบันทึกสถานะของอ็อบเจ็กต์ในฐานข้อมูล (ให้ใช้คลาส User เป็นตัวอย่าง) ถัดไปยกเลิกการกำหนดค่าข้อมูลเพื่อโหลดสถานะก่อนหน้ากลับไปที่อ็อบเจ็กต์ (เมธอดไม่ใช่ตัวต่ออนุกรมคุณต้องรวมคลาสอ็อบเจ็กต์เพื่อให้สามารถใช้งานได้ มัน)
    • การปรับเปลี่ยนผู้ใช้

หมายเหตุสำหรับวัตถุคุณควรใช้เมธอด magic __sleep และ __wakeup __sleep เรียกโดย serialize () วิธีการนอนหลับจะส่งคืนอาร์เรย์ของค่าจากวัตถุที่คุณต้องการคงอยู่

__wakeup ถูกเรียกโดย unserialize () วิธีการปลุกควรใช้ค่าที่ไม่ได้กำหนดค่าเริ่มต้นและเริ่มต้นในค่าเหล่านี้ในวัตถุ

สำหรับการส่งผ่านข้อมูลระหว่าง php และ js คุณจะใช้ json_encode เพื่อเปลี่ยน php array เป็นรูปแบบ json ที่ถูกต้อง หรือวิธีอื่น ๆ - ใช้ JSON.parese () เพื่อแปลงข้อมูลเอาต์พุต (สตริง) เป็นวัตถุ json ที่ถูกต้อง คุณต้องทำเช่นนั้นเพื่อใช้ประโยชน์จากพื้นที่จัดเก็บในตัวเครื่อง (การเข้าถึงข้อมูลออฟไลน์)


ทำไมต้องทำให้เป็นอนุกรมหากมี json_encode กรุณาอธิบายหากคุณทราบ ขอบคุณ
Yevgeniy Afanasyev

1
คุณจะได้รับประโยชน์จากความสามารถในการปรับแต่งวิธีการใช้เวทมนตร์ที่เป็นสีเมื่อใช้การทำให้เป็นอนุกรมและแบบไม่ต่อเนื่อง ที่กล่าวว่าคุณสามารถใช้ Json_encode () และ json_decode () ได้ไกลกว่ามากและแต่ละวัตถุสามารถจัดการกับ functinos นี้ได้ด้วยวิธีที่ไม่เหมือนใคร นี่คือเหตุผลที่คุณต้องการใช้
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)

ฉันหวังว่านี่จะช่วยคุณได้


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.