【问题标题】:Non-destructive JSON encoding/decoding of associative PHP arrays (containing objects)关联 PHP 数组(包含对象)的非破坏性 JSON 编码/解码
【发布时间】:2012-10-13 05:29:27
【问题描述】:

我能够JSON 以解码值与原始输入匹配的方式对索引数组进行编码和解码:

$array_indexed = ['A'];
$encoded = json_encode($array_indexed); 
$decoded = json_decode($encoded);
var_dump($array_indexed);
array(1) {
  [0]=>
  string(1) "A"
}
var_dump($decoded);
array(1) {
  [0]=>
  string(1) "A"
}

但是,当我对关联数组进行编码时,我最终得到了一个对象:

$array_associate = [ 'FOO' => 'BAR'];
$encoded = json_encode($array_associate);
$decoded = json_decode($encoded);
var_dump($array_associate);
array(1) {
  ["FOO"]=>
  string(3) "BAR"
}
var_dump($decoded);
object(stdClass)#1 (1) {
  ["FOO"]=>
  string(3) "BAR"
}

我的理解是这是正常行为,因为Javascript 不支持关联数组,而是使用对象来表示,因此在编码关联数组时,它最终被编码为对象(因此被解码) .

Q1:你确认了吗?

可能的解决方案

serialize /unserialize:
绝对要使用json_encode/json_decode 而不是serialize /unserialize 的原因是编码形式更加简洁,这很重要,因为它最终存储在缓存中并且缓存空间有限:

var_dump(json_encode(['A'=>1,'B'=>2])); // string(13) "{"A":1,"B":2}"
var_dump(serialize(['A'=>1,'B'=>2])); //   string(30) "a:2:{s:1:"A";i:1;s:1:"B";i:2;}

Q2:你有没有遇到过使用serialize的缓存空间问题,如果是这样,除了使用json_encode之外,你是如何解决的(我在考虑压缩,但如果价值结束在 MySQL 数据库缓存中我有点不安)?

json_decode($json,true)
问题是应该保留对象的嵌套对象也被转换为数组:

$obj = new stdClass;
$obj->foo = 'bar';
$array_associate = [ 'A' => $obj];
$encoded = json_encode($array_associate);
var_dump(json_decode($encoded,true));
array(1) {
  ["A"]=>
  array(1) {     <---------------- NO LONGER AN OBJECT, DON'T WANT THAT
    ["foo"]=>
    string(3) "bar"
  }
}

将对象对象转换为对象数组:

还是基于上面的例子

$object_of_objects = json_decode($encoded);
$array = [];
foreach($object_of_objects as $key=>$object) {
    $array[$key] = $object;
}
var_dump($array);
array(1) {                
  ["A"]=>
  object(stdClass)#6 (1) {
    ["foo"]=>
    string(3) "bar"
  }
}

Q3:您是否看到任何其他解决方案可以在保留原始输入的同时将关联的对象数组转换为 JSON 并返回?

【问题讨论】:

  • 谢谢,但我已经知道了(请参阅“问题是应该保留对象的嵌套对象也转换为数组”)。
  • 你的问题太长了,所以我没有注意到 :) 我认为还有其他 PHP 库可以创建 json。可能看那里(抱歉,我头上没有链接/名称)。
  • 确实很长,也许我应该瞄准更简洁一些。
  • 或者只是在顶部添加摘录。

标签: php json object serialization associative-array


【解决方案1】:

Q1:是的,PHP 关联“数组”(严格来说实际上不是数组)在转换为 JSON 时会转换为 Javascript 对象。为什么这对你来说是个问题?

Q2:我会使用 JSON 而非序列化,不仅因为它更简洁,还因为它得到更广泛的支持,并且在使用 UTF-8 编码文本时不会出现问题。

如果不希望json_decode()将JS对象转换为数组,则将第二个参数设置为false。

问题(不是听起来刺耳的意思):为什么你对数组上的对象如此着迷?在 PHP 中使用后者非常容易,即使在像 PDO 这样的 DB 抽象层中也是如此。

【讨论】:

  • json_decode() 将第二个参数设置为 false 不适用于对象的关联数组:如问题所示,关联数组本身被转换为对象(所以当我使用 @ 987654325@ 在插入缓存之前和从缓存中检索之后比较值,assertEquals 给我错误。至于你的问题,我没有挂断对象,我只是发现它们比数组更具可读性(我更喜欢$obj-&gt;value $obj['value'])。
  • 就我而言,我并没有“挂断”对象。我正在存储 Wordpress 帖子对象 - 所以当我检索它们时,它们需要采用对象格式。数组将无法使用。但我还需要存储这些对象的数组,以便我可以毫不费力地遍历它们。目前 json_encode 正在将整个对象数组转换为“对象对象”。顺便说一句,我发现虽然我写入的缓存文件更长,但序列化非常适合这个。它也是不可读的,但由于这只是一个缓存文件,这应该不是问题。
【解决方案2】:

由于无法在json中写入关联数组,因此将其写入为对象,因此PHP在解码时会将其作为对象。

为了让 PHP 将其作为数组读取,您必须 set the second parameter of json_decode to true:

json_decode($json, true)
                   ^^^^

【讨论】:

  • 谢谢,但我已经知道了(请参阅“问题是应该保留对象的嵌套对象也转换为数组”)。
  • 好吧,在那种情况下,json 不是你的答案
猜你喜欢
  • 2015-09-20
  • 2015-03-27
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 2018-12-27
相关资源
最近更新 更多