PHP中的序列化或json?

Posted

技术标签:

【中文标题】PHP中的序列化或json?【英文标题】:Serialize or json in PHP? 【发布时间】:2011-02-04 04:58:41 【问题描述】:

所以我需要在 php 中编码一个数组并将其以纯文本形式存储在 mysql 数据库中,我的问题是我应该使用 serialize() 还是 json_encode()?它们各自的优缺点是什么?

我认为在这种情况下他们中的任何一个都会这样做。但是你更喜欢哪一个,为什么?如果它是用于数组以外的东西?

【问题讨论】:

你要存储什么样的数组?大多数新手都错误地使用关系数据库并滥用它。为这样的数组制作一个表格总是更好 具有可变/可变索引和可变数量项目的数组。为数据创建表结构几乎是不可能的。 重复***.com/questions/804045/… 当心关联数组与使用 JSON 的 stdClass 对象 ..jondavidjohn.com/blog/2012/09/… 【参考方案1】:

serialize 的主要优点:它是 PHP 特有的,这意味着 它可以表示 PHP 类型,包括您自己的类的实例——并且您将得到您的对象,仍然是你的类,在反序列化你的数据时。

json_encode 的主要优点:JSON 并不特定于 PHP:有一些库可以用多种语言读/写它——这意味着如果你想要 可以用另一种语言操作的东西会更好PHP。

JSON 字符串也比序列化字符串更容易手动读取/写入/修改

另一方面,由于 JSON 不是 PHP 特有的,它不知道 PHP 特有的东西——比如数据类型。

作为一些旁注:

即使这两者之间的速度差异很小,也应该无关紧要:您可能不会序列化/反序列化大量数据 您确定这是在数据库中存储数据的最佳方式吗? 您将无法在数据库中对序列化字符串进行大量查询:您将无法在 where 子句中使用您的数据,也无法在没有 PHP 干预的情况下更新它...

【讨论】:

从 PHP 5.4.0 开始,您现在可以通过实现 JsonSerializable 接口来自定义 JSON 序列化。 最后一点 - 没有理由不能在 WHERE 子句中使用序列化/json 字符串的内容。整个想法是这两种方法将复杂类型(如数组和对象)归结为字符串表示。如果您正在考虑使用数据库,我同意有更好的方法来做到这一点。我还想为json_encode'd 字符串添加一个凹凸:它更健壮,因为它的值不依赖于长度。【参考方案2】:

首先序列化一个数组或对象并将其存储在数据库中通常是一种代码味道。有时人们最终将逗号分隔的列表放入列中,然后当他们后来发现需要对其进行查询时遇到各种麻烦。

所以如果是这种情况,请仔细考虑一下。

至于差异。 PHP 序列化可能更紧凑,但仅适用于 PHP。 JSON 是跨平台的,编码和解码速度可能更慢(尽管我对此表示怀疑)。

【讨论】:

这可能有有效的用例。例如数据库队列。在处理队列中的记录时,从不查询 Blob,而只是反序列化。 WordPress 是 PHP 的一个常见示例,posts 表的性质将用户推向这种结构。所以在这种情况下,它适用于编码环境,即使它显然不是关系型的。【参考方案3】:

如果您的数据永远不必离开您的 PHP 应用程序,我建议您使用 serialize(),因为它为您的对象提供了很多额外的功能,例如 __sleep() 和 __wakeup() 方法。它还将对象恢复为正确类的实例。

如果要将序列化数据传递给另一个应用程序,则应使用 JSON 或 XML 以实现兼容性。

但是将序列化的对象存储到数据库中?也许你应该再考虑一下。以后可能会很麻烦。

【讨论】:

【参考方案4】:

json_encode 相对于serialize 的另一个优势是尺寸。我注意到,当我试图弄清楚为什么我们的memcache 使用的内存变得如此之大时,我正试图找到减少的方法是:

<?php

$myarray = array();
$myarray["a"]="b";
$serialize=serialize($myarray);
$json=json_encode($myarray);
$serialize_size=strlen($serialize);
$json_size=strlen($json);
var_dump($serialize);
var_dump($json);
echo "Size of serialized array: $serialize_size\n";
echo "Size of json encoded array: $json_size\n";
echo "Serialize is " . round(($serialize_size-$json_size)/$serialize_size*100) . "% bigger\n";

这给了你:

string(22) "a:1:s:1:"a";s:1:"b";"
string(9) ""a":"b""
Size of serialized array: 22
Size of json encoded array: 9
Serialize is 59% bigger

显然我举了一个最极端的例子,因为数组越短,序列化的开销就越重要(相对于初始对象大小,因为无论内容多么小,格式都会施加最少的字符数)。我仍然在生产网站上看到序列化数组比对应的 json 大 20%。

【讨论】:

【参考方案5】:

我对 PHP 中的 Json Encoding vs Serialization 做了一些分析。而且我发现 Json 最适合像数组这样简单明了的数据。

在https://www.shozab.com/php-serialization-vs-json-encoding-for-an-array/查看我的实验结果

【讨论】:

json_(encode/decode) 与 serialize()/unserialize() 的性能概览。我很想看到您的博客(或此处)添加一些其他观点,因为我不是性能专家。【参考方案6】:

首先,感谢 Shozab Hasan 和 user359650 进行这些测试。我想知道哪个选择是最好的,现在我知道了:

要编码一个简单的数组,JSON 可以用于 PHP 和 javascript,也许是其他语言。

要编码 PHP 对象,序列化是更好的选择,因为 PHP 对象的特殊性只能用 PHP 实例化。

要存储数据,可以将编码数据存储在文件中,也可以使用标准格式的 MySQL。取回您的数据会容易得多。 MySQL 具有强大的功能,可以按照您想要的方式获取数据,无需 PHP 处理。

我从未做过任何测试,但我认为如果系统文件排序足以按字母/数字顺序取回文件,那么文件存储是存储数据的最佳方式。 MySQL对这种处理很贪心,也用文件系统……

【讨论】:

以上是关于PHP中的序列化或json?的主要内容,如果未能解决你的问题,请参考以下文章

PHP反序列化总结

JSON PHP中,Json字符串反序列化成对象/数组的方法

如何根据json中的属性编写jackson反序列化器

php 序列化json

json与pickle模块

json与pickle模块