【问题标题】:How do "scalar" PHP arrays work under the hood?“标量”PHP 数组如何在幕后工作?
【发布时间】:2019-11-13 20:31:35
【问题描述】:

背景

本周我遇到了一个有趣的根本原因的问题。问题在于 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 对象?它内部是否有类似于以下内容的业务逻辑:

如果:

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

?

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

【问题讨论】:

  • 您的第一个示例不需要跟踪数组键,因为它们是数字和顺序的,您的第二个示例需要跟踪它们,因为它们不是顺序的。您的问题“本质上是“速记”...”的答案是肯定的。 json_encode() 不应该返回数组或对象,它返回一个字符串。
  • @GrumpysaysReinstateMonica 抱歉,澄清一下我的意思是一个 JSON 对象(在字符串中)。我将编辑问题。顺便说一句,这条评论 100% 可以作为答案,你点击了所有内容
  • 如果您需要始终返回 JSON 数组,请在编码前使用 array_values()。 PHP 将稀疏数组视为关联数组,因此在转换为 JSON 时总是会产生一个对象。

标签: php arrays serialization


【解决方案1】:

让我们以您的第一个示例并将其与您的第二个示例进行比较

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 时总会产生一个对象。

【讨论】:

    猜你喜欢
    • 2018-04-16
    • 2014-11-18
    • 2011-02-17
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多