如何使用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 =大小为{}内的三个元素。在其中,您拥有等于1的i =整数/索引,len 6的字符串等于“ elem 1”,等于2的整数,等等。等等。您可以想象很容易在其中包含多个级别的数组/对象,但是修改是非常不明智的,您应该真正反序列化Modify然后序列化以确保一致性。
2015年

2
@ IstiaqueAhmed,关于“任何人都可以给出一个例子,说明我需要在使用它之前先序列化一个php数组”,在stackoverflow.com/a/30436890/632951中
Pacerier,2015年

@grizly谢谢您,两年来我一直在寻找这样的答案,我既不知道如何解释它,也不知道如何使用该功能的原因,感谢您的答案
isaacewing

Answers:


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
我们的解释似乎正在接近我的期望。你能看看我的编辑吗?
Istiaque Ahmed 2011年

1
a:3:{i:1; s:6:“ elem 1”; i:2; s:6:“ elem 2”; i:3; s中的a,i,s等的解释是什么: 7:“ elem 3”;}?而且,如果您不介意,可以使用序列化数组的示例(可能与本主题无关)以将其发送给js。
Istiaque Ahmed 2011年

2
据我所知,几乎找不到该格式的正式规范,但是您可以猜测,不是吗?i:1=整数1,s:6:"elem 1"=包含6个字符的字符串“ elem 1” ......您想问什么示例,我以为我给了一个?
deceze

“但是您如何将这个数组传递给Javascript?数组([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中显示示例(如有必要)?
伊斯蒂亚·艾哈迈德

2
@Istiaque Ahmed例如,当您要将数组存储到磁盘上的文件时,您不能直接保存数组,而是将其转换为可存储的值,即字符串。
xdazz

但是我们可以直接将变量插入数据库,而无需在php mysql中序列化它。请解释。
Istiaque Ahmed 2011年

9
“我们可以将变量插入数据库而无需序列化”。这仅适用于基本数据类型(字符串,整数,数字)。我们不能将数组和对象直接插入数据库或文件系统中。这就是serialize()unserialize()被用于制造。
lorenzo-s

您需要一些信息并在php脚本中进行一些处理,以准备将其存储/发送到某个地方。您可以选择创建一个与期望数据完全匹配的表,但这很麻烦,因为您必须编写也要匹配的代码,而且您需要对代码进行更改,所以实际上您的工作量加倍了,反之亦然。序列化后,您可以简单地创建一个具有两列id int(10)和信息BLOB的表。序列化为您提供一个要插入的字符串,反序列化会将数据恢复为原始状态。在某些情况下,PHP文档将涵盖这些内容。
克里斯(Chris

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 2011年

如果存在json_encode,为什么需要序列化?如果您知道,请说明。谢谢。
Yevgeniy Afanasyev

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
如果提供的代码包含多个安全漏洞,则应警告来访者和复制粘贴代码。
Daniel W.

给定的代码只是如何使用searilize和unserialize函数的示例。
Avnish alok

2

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

生成值的可存储表示形式。这对于在不丢失其值和结构的情况下存储或传递PHP值很有用。

本质上,它需要一个php数组或对象并将其转换为字符串(然后您可以根据需要传输或存储该字符串)。

Unserialize用于将字符串转换回对象。


“可存储表示”的解释是什么?
Istiaque Ahmed 2011年

香港专业教育学院只看到序列化用于某人想要一个php数组并将其存储在数据库中时。您可以序列化输出,将输出存储在数据库的标准字符串字段中,然后在要再次使用它时对其进行抓取和反序列化。
MrGlass 2011年

1

基本上,当序列化数组或对象时,只需将其转换为有效的字符串格式,以便可以轻松地将其存储在php脚本之外。

  1. 使用序列化将对象的状态保存在数据库中(以User类为例)接下来,对数据进行反序列化以将先前的状态加载回该对象(方法不是序列化程序,您需要包括对象类才能使用它)
    • 用户个性化

请注意,对于对象,您应该使用魔术__sleep和__wakeup方法。__sleep由serialize()调用。sleep方法将从您要保留的对象中返回值的数组。

__wakeup由unserialize()调用。唤醒方法应采用未序列化的值,然后在对象中的值中对其进行初始化。

为了在php和js之间传递数据,您可以使用json_encode将php数组转换为有效的json格式。或者以其他方式-使用JSON.parese()将输出数据(字符串)转换为有效的json对象。您可能想要这样做以利用本地存储。(离线数据访问)


如果存在json_encode,为什么需要序列化?如果您知道,请说明。谢谢。
Yevgeniy Afanasyev

1
您可以受益于能够自定义在使用序列化和反序列化时遇到的魔术方法。也就是说,您可以进一步使用Json_encode()和json_decode(),并且每个对象都可以以其独特的方式处理此functinos。这就是为什么您想使用它们。
DevWL

1
还有更多的东西。有关更多信息
请参见此

1
json_encode更快(取决于您使用的PHP版本),json解码为stdClass,序列化的对象反序列化为实际的Class实例,我对JSON进行了一些配置,以保留UTF-8编码不变,序列化不会更改编码。如果要使跨平台的数据使用JSON,如果仅在PHP中工作,则可以使用__sleep和__wakeup魔术方法来自定义序列化。
DevWL '17

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, '"');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.