“标量” PHP数组如何在后台运行?

时间:2019-11-13 20:31:35

标签: php arrays serialization

背景

本周,我遇到了一个有趣的根本原因。问题在于PHP数组如何工作。我有一个使用 array_filter 的API终结点,有时返回JSON对象,有时返回JSON数组。这里有一些例子:

json_encode([0 => 1, 1 => 2, 2 => 3])

返回字符串

"[1,2,3]"

但是,以下代码:

json_encode([0 => 1, 2 => 2, 3 => 3])

返回字符串:

"{"0":1,"2":2,"3":3}"

我的问题

PHP在“标量”(非地图)数组的底层做什么?

说我有一个

数组
[1, 2, 3]

从本质上讲,是这样的“简写”:

[0 => 1, 1 => 2, 2 => 3]

最后,json_encode如何返回JSON数组而不是JSON对象?它内部是否包含类似于以下内容的业务逻辑:

IF:

  • 索引从0开始
  • 索引在LENGTH-1
  • 处结束
  • 索引的排列顺序从小到大
  • 两个相邻索引之间的差异始终为1

This PHP 8.0 RFC是否会对JSON序列化程序造成破坏?

1 个答案:

答案 0 :(得分:3)

让我们以您的第一个示例为例,然后将其与第二个示例进行比较

json_encode([0 => 1, 1 => 2, 2 => 3]); //returns "[1,2,3]"
//versus
json_encode([0 => 1, 2 => 2, 3 => 3]); //returns "{"0":1,"2":2,"3":3}"

生成的JSON字符串有所不同,因为在您的第一个示例中,返回的字符串不需要跟踪数组键。这是因为它们是数字的和顺序的。

在第二个示例中,密钥是不是顺序的,因此生成的JSON字符串需要跟踪密钥,以便可以对其进行正确解码。

[1, 2, 3]等于[0 => 1, 1 => 2, 2 => 3]。唯一的区别是显式说明了键,这不是必需的,并且在未指定键的情况下会自动完成。 (将始终是顺序的和数字的)

此外,json_encode()永远不要返回数组或对象,它应该返回字符串。在注释中,您澄清了您的意思是“ JSON对象”,但是我认为前提是有缺陷的,因为它从不返回PHP数组,它总是返回JSON对象。结果字符串的复杂性不会改变它是JSON对象。

Miken32 noted一样,如果您始终希望返回的内容不太复杂(忽略键),则可以在编码之前使用array_values()。 PHP将稀疏数组视为关联数组,因此在转换为JSON时始终会生成一个对象。