如何使用 php serialize() 和 unserialize()

Posted

技术标签:

【中文标题】如何使用 php serialize() 和 unserialize()【英文标题】:How to use php serialize() and unserialize() 【发布时间】:2012-01-28 08:07:22 【问题描述】:

我的问题很基础。

关于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数组吗?

【问题讨论】:

如果您仍然对“辅助输出”感到好奇,它相当简单:a = 数组,3 = 中的三个元素。在其中,你有 i=integer/index 等于 1,len 6 的字符串等于“elem 1”,整数等于 2.. 等等等等。当你这样阅读时,它相当清楚。你可以想象很容易包含多个级别的数组/对象,但是修改是非常不明智的,你应该真正反序列化修改然后序列化以确保一致性。 @IstiaqueAhmed,关于“谁能举个例子说明我需要在使用它之前序列化一个php数组”,***.com/a/30436890/632951有这样一个例子 @grizly 谢谢伙计,两年来我一直在寻找这样的答案,我不知道如何解释,也不知道如何关联使用该功能的原因,谢谢回答 【参考方案1】:

PHP 数组或对象或其他复杂数据结构不能在正在运行的 PHP 脚本之外传输、存储或以其他方式使用。如果您想在单次运行脚本之外持久化这样一个复杂的数据结构,您需要序列化它。这只是意味着将结构放入一个“较低的公分母”中,可以由 PHP 以外的东西处理,比如数据库、文本文件、套接字。标准的 PHP 函数 serialize 只是 一种格式 来表达这样的事情,它将数据结构序列化为 PHP 独有的字符串表示形式,并且可以使用 unserialize 反转为 PHP 对象。不过还有许多其他格式,例如 JSON 或 XML。


以这个常见问题为例:

如何将 PHP 数组 传递给 javascript

PHP 和 Javascript 只能通过字符串进行通信。你可以很容易地将字符串"foo" 传递给Javascript。您可以非常轻松地将数字 1 传递给 Javascript。您可以轻松地将布尔值 truefalse 传递给 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>

在很多情况下,您需要将复杂的数据结构作为字符串传递。序列化,将任意数据结构表示为字符串,解决了如何做到这一点。

【讨论】:

你的解释似乎接近我的预期。你能看看我的编辑吗? a:3:i:1;s:6:"elem 1";i:2;s:6:"elem 2 中的 a,i,s 等的解释是什么";i:3;s:7:" 元素 3"; ?如果你不介意,一个序列化数组的示例(可能与本文的主题无关)以将其发送到 js。 据我所知,几乎找不到该格式的正式规范,但您可以猜到,不是吗? i:1 = 整数 1,s:6:"elem 1" = 6 个字符的字符串“elem 1”......你要什么例子,我想我给了一个? " 但是如何将这个数组传递给 Javascript?Array ( [1] => elem 1 [2] => elem 2 [3] => elem 3 ) "...代码 sn-p echo json_encode($array); 你如何准确通过这取决于具体情况。不要太在意这个。【参考方案2】:

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

我希望这会有所帮助

【讨论】:

【参考方案3】:
<?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=数组值的大小

您可以使用序列化将数据数组存储在数据库中并且可以检索和取消序列化数据以使用。

【讨论】:

【参考方案4】:

当你想让你的php值可存储时,你必须把它变成一个字符串值,这就是serialize()所做的。而unserialize() 则相反。

【讨论】:

'storable' 是什么意思?我已经浏览了你提到的页面。你能用php和mysql(如果需要的话)显示一个例子吗? @Istiaque Ahmed 例如,当您要将数组存储到磁盘上的文件时,您不能直接保存数组,而是将其转换为可存储的值,即字符串。跨度> 但是我们可以直接将一个变量插入到数据库中,而不用在php mysql中序列化它。请解释一下。 “我们可以在不序列化的情况下将变量插入数据库”。这仅适用于基本数据类型(字符串、整数、数字)。我们不能直接将数组和对象插入数据库或文件系统。这就是 serialize()unserialize() 的用途。 您获取一些信息并在您的 php 脚本中对其进行一些处理,以便将其存储/发送到某个地方。您可以选择创建一个与预期数据完全匹配的表,但这很乏味,因为您必须编写匹配的代码,而且数据库的更改需要更改代码,反之亦然。序列化后,您可以简单地创建一个包含两列 id int(10) 和信息 BLOB 的表。 Serialise 为您提供一个要插入的字符串,反序列化将数据返回到其原始状态。在某些情况下它不会,php 文档涵盖了这些情况。【参考方案5】:

大多数存储介质都可以存储字符串类型。它们不能直接存储 PHP 数据结构,例如数组或对象,也不应该,因为这会使数据存储介质与 PHP 耦合。

相反,serialize() 允许您将这些结构之一存储为字符串。可以使用 unserialize() 将其从其字符串表示中反序列化。

如果您熟悉 json_encode()json_decode()(以及一般的 JSON),则概念类似。

【讨论】:

熟悉json。在php的事情上仍然默默无闻。编辑了我的帖子 如果有json_encode为什么需要序列化?知道的请解释一下。谢谢。 @YevgeniyAfanasyev 也许你不喜欢某些数据子集。但我认为 serialize() 早于 JSON。【参考方案6】:

请!请!请!不要序列化数据并将其放入数据库中。可以以这种方式使用序列化,但这缺少关系数据库的要点和数据库引擎中固有的数据类型。这样做会使数据库中的数据不可移植、难以阅读,并且会使查询复杂化。如果您希望您的应用程序可移植到其他语言,例如假设您发现您想在应用程序的某些部分使用 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']));

【讨论】:

提供的代码包含多个安全漏洞,应警告路过和复制粘贴代码的人。 给出的代码只是一个示例,说明如何使用 searilize 和 unserialize 函数。【参考方案7】:

来自http://php.net/manual/en/function.serialize.php:

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

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

反序列化用于将字符串转换回对象。

【讨论】:

“可存储表示”的解释是什么? 只有在有人想要获取 php 数组并将其存储在数据库中时才看到使用序列化。您可以序列化,将输出存储在数据库中的标准字符串字段中,然后在您想再次使用它时抓取并反序列化它。【参考方案8】:

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

    使用序列化将对象的状态保存在数据库中(以User类为例)接下来反序列化数据以将先前的状态加载回对象(方法不是序列化器,您需要包含对象类可以使用) 用户个性化

注意对象你应该使用魔法 __sleep 和 __wakeup 方法。 __sleep 由 serialize() 调用。一个 sleep 方法会从你想要持久化的对象中返回一个值数组。

__wakeup 由 unserialize() 调用。唤醒方法应采用未序列化的值并在对象中将它们初始化。

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

【讨论】:

如果有json_encode为什么需要序列化?知道的请解释一下。谢谢。 您可以从能够自定义使用序列化和反序列化时收集的魔术方法中受益。也就是说,您可以进一步使用 Json_encode() 和 json_decode() ,并且每个对象都可以以独特的方式处理此功能。这就是您想要使用它们的原因。 还有更多内容。有关更多信息,请参阅此答案***.com/questions/804045/… json_encode 更快(取决于您使用的 PHP 版本),json 解码为 stdClass,序列化对象反序列化为实际 Class 实例,我必须对 JSON 进行一些配置以保持 UTF-8 编码不变, serialize 不会更改编码。如果你想让数据跨平台使用 JSON,如果你只使用 PHP,你可以使用 __sleep 和 __wakeup 魔术方法来自定义序列化。【参考方案9】:

是的,我可以。假设我们需要跟踪您的系统意味着在您的系统中有多个管理员和子管理员,所有这些都可以插入或更新或编辑任何信息。稍后您需要知道是谁进行了此更改。为了解决这个问题,你需要序列化。

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

希望对你有帮助。

【讨论】:

【参考方案10】:
preg_match_all('/\".*?\"/i', $string, $matches);
foreach ($matches[0] as $i => $match) $matches[$i] = trim($match, '"');

【讨论】:

以上是关于如何使用 php serialize() 和 unserialize()的主要内容,如果未能解决你的问题,请参考以下文章

PHP变量处理之serialize

那些技术php的serialize序列化和json性能测试(上)

php serialize的长度问题,大神来

关于php的session.serialize_handler的问题

php的serialize()函数和unserialize()函数

php中serialize后的数据 怎么使用java来解析,java有没有类似PHP中unserialize的方法