【问题标题】:json_encode changing array with one value to objectjson_encode 将数组与一个值更改为对象
【发布时间】:2014-10-30 14:10:26
【问题描述】:

我正在创建一个处理 JSON 输入的 PHP 脚本(通过 $_POST 变量)。它从 JSON 中提取数据并将其上传到 SQL 数据库。我想要特定格式的 JSON:

$object = json_decode('{
    "key_a":[{"value_a":10,"value_b":7},{"value_a":10,"value_b":7},{"value_a":10,"value_b":7}],
    "key_b":[{"value_a":10,"value_b":7}],
    "key_c":[{"value_a":10,"value_b":7},{"value_a":10,"value_b":7}]
    }',true);

基本上,一个带有键的对象,每个键都应该包含一个数组(无论它是什么大小)。我使用 json_decode(json,true) 将其转换为关联数组(而不是对象)。我必须为每个键添加大量检查,检查它们是否是对象或数组(作为提取来自的 ASP.net 页面将具有单个对象的数组转换为对象 - 删除数组持有他们)。然后检查将它们转换回数组,如果有一个对象我想要一个包含对象的数组:

if(is_object($object["key_b"]))
{
    $a = array();
    $a[] = $object["key"];
    $object["key"] = $a;
}

然后我遍历数组,将值添加到 SQL 数据库中的行。这一切都很好,但是当使用 json_encode 转换回 JSON 时,任何包含只有一个对象的数组的键,删除该数组,并只留下该键下的对象:

echo(json_encode($object));
// RETURNED JSON  
'{
        "key_a":[{"value_a":10,"value_b":7},{"value_a":10,"value_b":7},{"value_a":10,"value_b":7}],
        "key_b":{"value_a":10,"value_b":7},
        "key_c":[{"value_a":10,"value_b":7},{"value_a":10,"value_b":7}]
    }'

你看,key_b 不再是一个数组,而是一个对象!这真的很烦人,因为我计划创建一个遍历数组的 JavaScript 脚本,为每个对象添加一个 DOM 元素 (div)。

为什么会这样?有没有办法将它们保留为数组,即使数组中只有一个对象?

我试过了:

if(is_object($object["key_b"]))
{
    $a = array();
    $a[] = array_values($object["key"]);
    $object["key"] = $a;
}

if(is_object($object["key_b"]))
{
    $a = array();
    $a[0] = array_values($object["key"]);
    $object["key"] = $a;
}

但似乎没有什么可以阻止 json_encode 以这种方式影响 JSON。

解决这个问题并不难 - 但这意味着每个键添加一个检查(检查它是数组还是值),这特别耗时,因为通过的数据提取非常大。

任何建议将不胜感激。

编辑:在 JSON 中将 ' 更改为 " - 不过,这只是我刚刚编写的用于显示结构的示例。

编辑:我正在使用引用来缩短我的编码时间,如果这改变了什么?:

$t =& $object["key_b"];
if(is_object($t))
{
    $a = array();
    $a[] = $t;
    $t = $a;
}

【问题讨论】:

  • Javascript/JSON 所称的“对象”和 PHP 所称的对象是完全不同的。 $object["key"] 到底是什么? if 中的代码是否曾经被执行过?
  • 我只是把它写成一个例子——这不是我实际使用的 JSON,抱歉。
  • 嗯,好问题,deceze - 我不确定!我把它当作 javascript 对待对象/数组。
  • 我编辑了 OP 以显示我所说的 object["key"] 的意思。
  • 我认为你应该使用is_array而不是is_object,因为当json字符串被解码为关联数组时会返回数组。

标签: php json


【解决方案1】:

似乎在关联数组的键上使用 is_object() 不会返回 true。我只是敲了这个例子来证明这一点:

$json = json_decode('{"job_details":{"a":[{"x":5},{"y":23},{"z":18}],"b":{"x":19},"c":[{"x":64},{"y":132}]}}',true);

echo(json_encode($json)."<br><br>");

$t =& $json["job_details"]["b"];
if(is_object($t))
{
    $a = array();
    $a[] = $t;
    $t = $a;
    echo("IS OBJECT<br><br>");
}

echo(json_encode($json));

我会找到另一种方法来检查关联数组键中保存的值。

我实际上试图找出键中的值是否是关联数组(不是对象)——我只是没有意识到它们在 PHP 中是不同的。

我必须使用这个自定义函数:

function is_assoc($array) 
{
    return (bool)count(array_filter(array_keys($array), 'is_string'));
}

发件人:How to check if PHP array is associative or sequential?

如果值是关联数组,则返回 true。

【讨论】:

  • 不是真的。 is_object 测试对象。你的数组值碰巧不是一个。所有 php 数组都是双模式的。关联+顺序。 PHP 不在乎。但$a['foo'] = new StdClass; var_dump(is_object($a['foo'])) 将返回 true。
  • 是的,但是当使用 json_decode() 时,您可以将其用作 json_decode($string) 将 JSON 转换为对象,或 json_decode(string,true) - 将 JSON 转换为关联数组。
猜你喜欢
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多