【问题标题】:How can I ensure all key names in a PHP generated JSON are strings?如何确保 PHP 生成的 JSON 中的所有键名都是字符串?
【发布时间】:2013-01-06 07:25:12
【问题描述】:

我有一个 PHP 脚本,它输出 JSON 数据,这些数据由浏览器中的 Javascript 以及 iPhone 和 Android 应用程序解析。

之前我发现PHP在将数组数据转换成JSON时,会将所有数字值变成双引号所表示的字符串。因此,例如,"id" : 1 将变为 "id" : "1"。这似乎混淆了一些接收 JSON 数据的 Javascript 函数,所以我在 PHP 中的 JSON 上运行了这个正则表达式,以确保数字不会变成字符串:

$JSONOutput = preg_replace('/"(-?\d+\.?\d*)"/', '$1', json_encode($JSONOutput));

但是,这也具有从键和值中删除双引号的效果,因此1 : "first value" 变为"1" : "first value"。事实证明这是一个问题,因为如果 JSON 键不是字符串,那么接收数据的 iPhone 应用程序就会抱怨。

所以,我想要做的是确保 JSON 中的所有值都保留为整数,但所有键都制成字符串。有没有一种方法可以只在值上运行我上面的正则表达式?或者任何其他可以给我类似结果的过程?

【问题讨论】:

  • 我不明白。 JSON 对象的键是 always 字符串。你的问题令人困惑。您能否展示一个数组的具体示例以及它是如何编码的以及您想对其进行哪些更改?
  • 不要转换json_encode输出,修改你发送给它的输入。使用array_walk_recursive 遍历所有值并使用is_numeric($value) ? floatval($value) : $value 或类似的东西进行转换。
  • @DCoder:听起来不错。你能在答案中提供一个详细的例子吗?
  • 我认为 TJCrowder 的回答很好地解释了这个问题。 (另外,我的建议是相当严厉的。将数据转换为正确的数据类型不应该只是“如果它像数字一样走路并且像数字一样嘎嘎叫,将其转换为数字”,它应该使用领域知识来完成字段是数字,哪些不是。)
  • @DCoder 等人,通过探索这个问题,我意识到我的根本问题是我从 MySQL 获取值的方式。我已经打开 another question 来解决这个问题。

标签: php json


【解决方案1】:

有没有一种方法可以只对值运行上面的正则表达式?

好多最好避免对字符串进行后处理。

之前我发现PHP在将数组数据转换成JSON时,会将所有数字值变成双引号所表示的字符串。因此,例如,“id”:1 将变为“id”:“1”。

这里的答案是确保数字值确实是数字。如果您在期望数字的地方看到带有数字的字符串,那是因为 PHP 对象/数组中的值不是数字。这就是你需要解决的问题。

例如这段代码:

<?php
    header('Content-Type: application/json');
    $x = array(
        "number" => 1,
        "string" => "2"
        );
    echo json_encode($x);
?>

...非常正确地产生了这个输出:

{"number":1,"string":"2"}

注意 PHP 代码中真正是数字的值是如何在 JSON 中以数字形式出现的。

因此,与其对字符串进行后处理,不如更正您输入json_encode 的数据。


在下面回复您的评论:

我知道我可以专门为键分配字符串名称,但是有问题的数组是通过一个不断附加数字的 while 循环自动生成的,并且这些数字用于计数操作,所以我认为这不起作用就我而言。

这并没有什么区别。例如这段代码:

<?php
    header('Content-Type: application/json');
    $x = array();
    for ($n = 1; $n < 5; ++$n) {
       $x["entry" . $n] = $n;
    }
    echo json_encode($x);
?>

产生这个输出:

{"entry1":1,"entry2":2,"entry3":3,"entry4":4}

再次注意,输入中的数字是数字,因此输出中的数字也是如此。

还要注意,如果对象的 keys 是数字,PHP 会正确处理它:

<?php
    header('Content-Type: application/json');
    $x = array();
    $x["foo"] = "bar";
    for ($n = 1; $n < 5; ++$n) {
       $x[$n] = $n * 2;
    }
    echo json_encode($x);
?>

生产

{"foo":"bar","1":2,"2":4,"3":6,"4":8}

【讨论】:

  • 感谢您的回答。我知道我可以专门为键分配字符串名称,但是有问题的数组是通过一个不断附加数字的 while 循环自动生成的,并且这些数字用于计数操作,所以我认为这不适用于我的情况.
  • @DaveMG:没有任何区别,数字就是数字。我在上面给出了第二个例子。
猜你喜欢
  • 2023-03-28
  • 2011-02-06
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 2013-02-05
  • 1970-01-01
  • 1970-01-01
  • 2014-01-01
相关资源
最近更新 更多