PHP/json_encode:处理具有数字属性的混合数组和对象

Jos*_*son 5 php json associative-array

我最近不得不解决遗留 PHP 应用程序中的错误。此应用程序接收来自另一个应用程序的请求,其 JSON 格式为:

{
  "someList": [
    "item A",
    "item B"
  ],
  "ratings": {
    "0": 0.001234,
    "1": 0.0666,
    "2": 0.09876,
    "3": 0.777777
  }
}
Run Code Online (Sandbox Code Playgroud)

当它反序列化为原生 PHP “关联数组”时,列表和映射(键为 0、1、2 和 3)看起来都像列表。没关系,我可以解决这个问题。但是,此应用程序会对此数据进行计算,并在以大致相同的格式将其序列化回 JSON 并将其发送到另一个应用程序之前对其进行更多计算。这就是问题所在。json_encode($data)上述结果的开箱即用:

{
  "someList": [
    "item A",
    "item B"
  ],
  "ratings": [
    0.001234,
    0.0666,
    0.09876,
    0.777777
  ]
}
Run Code Online (Sandbox Code Playgroud)

我的钥匙都没了...

我看到我可以使用JSON_FORCE_OBJECTlaecho json_encode($data, JSON_FORCE_OBJECT)但后来我得到:

{
  "someList": {
    "0": "item A",
    "1": "item B"
  },
  "ratings": {
    "0": 0.001234,
    "1": 0.0666,
    "2": 0.09876,
    "3": 0.777777
  }
}
Run Code Online (Sandbox Code Playgroud)

现在我在第一个列表中得到了我不想要的键。有没有办法序列化这个 JSON,使其someList成为一个列表(没有键)并且ratings将是一个映射/对象(带有键 0、1、2 和 3)?

Jos*_*son 1

在通过 解码原始 JSON 时,能够通过使用stdClass而不是关联数组找到解决方案json_decode($json, false);。然后,当json_encode计算结果时stdClass,密钥将被保留。

这是一个完整的示例:

<?php

$json = <<<JSON
{
  "someList": [
    "item A",
    "item B"
  ],
  "ratings": {
    "0": 0.001234,
    "1": 0.0666,
    "2": 0.09876,
    "3": 0.777777
  }
}
JSON;

// Passing false for the second param (or omitting it)
// returns a stdClass instead of associative array
$data = json_decode($json, false);

echo json_encode($data, JSON_PRETTY_PRINT);
Run Code Online (Sandbox Code Playgroud)

哪个输出:

{
    "someList": [
        "item A",
        "item B"
    ],
    "ratings": {
        "0": 0.001234,
        "1": 0.0666,
        "2": 0.09876,
        "3": 0.777777
    }
}
Run Code Online (Sandbox Code Playgroud)