【问题标题】:Why is json_decode($data, TRUE) converting an array to a string?为什么 json_decode($data, TRUE) 将数组转换为字符串?
【发布时间】:2014-05-16 02:46:54
【问题描述】:

JavaScript 代码:

$.ajax({
  type: "POST",
  url: "postTestingResult.php",
  data: {data: JSON.stringify(sendData)},
  dataType: "json",
  success: ajaxSuccess,
  error: ajaxError
});

PHP 代码

$data = json_decode($_POST['data'], TRUE);

当我向服务器发布一个复杂的数据结构时,最外层的数组变成了一个字符串。例如,JavaScript 对象可以是

var data = {"apps": [[1,2,3], [4,5,6]]}

使用 JSON.stringify(data) 这变成了

"{"apps": "[[1,2,3], [4,5,6]]"}" //As seen via console.log(data) in Chrome console

但是在做了 json_decode($_POST['data'], TRUE) 之后就变成了

array('apps' => '[[1,2,3], [4,5,6]]') //As seen via var_export($data, TRUE)

这里发生了什么?为什么将数组转换为字符串?查看完整的 JSON 对象和完整的 PHP 对象check out this pastebin with the two

非常感谢任何帮助,谢谢。

更新:找到答案 我找到了罪魁祸首。我也在使用 Prototype.js,它正在向 Object 原型添加一个 toJSON 方法。 Check out this SO question for details.

【问题讨论】:

  • 看起来JSON.stringify() 有问题,因为那是嵌套数组变成字符串的时候。不过,仍在考虑可能发生的事情。
  • 那么,sendData 是一个对象字面量吗?您是否尝试过在没有JSON.stringify() 的情况下发送它。我认为您不需要 JSONify POSTed 对象文字数据。
  • @Darragh sendData 是一个复杂的数据对象。您可以在我链接到的 pastebin 中看到它的 JSON.stringify 版本。您可以将其(显然没有键/数据)视为:{[{[{[]},{[]}]},{[{[]},{[]}]}],{}}跨度>
  • @emab 我不会评估潜在的恶意代码。来自 php.net:“eval() 语言结构非常危险,因为它允许执行任意 PHP 代码。”除了 1)我不应该为此使用 eval 并且 2) eval 很慢!
  • @Sam 你在正确的轨道上!查看我发布的更新。 tl;dr:我还在我的代码中使用 Prototype.js,它正在向 Object 原型添加一个 toJSON 方法,如果它存在则由 JSON.stringify 调用

标签: javascript php json stringify


【解决方案1】:

试试这个。以application/json 明确发送您的数据,并且不要包装您的sendData

var sendData = {'apps': [[1,2,3], [4,5,6]]};

$.ajax({
  type: 'POST',
  url: 'postTestingResult.php',
  data: JSON.stringify(sendData), // don't wrap your JSONified object 
  contentType: 'application/json' // set application/json - default is x-form-urlencoded
});

注意标题和数据:application/json:

当然,正如您所强调的,现在$_POST 超全局中的数据将不可用。但这不是问题,获取 JSON 数据字符串的一种非常常见的方法是通过 php://input 读取 raw 帖子数据:

$data = array();
$json = file_get_contents('php://input'); // read JSON from raw POST data

if (!empty($json)) {
    $data = json_decode($json, true); // decode
}

print_r($data);

产量:

Array( 
  [apps] => Array ( 
    [0] => Array ( 
      [0] => 1 
      [1] => 2 
      [2] => 3 ) 
    [1] => Array ( 
      [0] => 4 
      [1] => 5 
      [2] => 6 
   ) 
))

希望这会有所帮助:)

编辑

请注意,PHP documentation 声明:

注意:使用 php://input 打开的流只能读取一次;该流不支持查找操作。

然而,iirc 这已经或将会改变(可能在 PHP 5.6 中?)。不过不要引用我的话,现在,如果你打算重用它,不要忘记分配该流的内容!

【讨论】:

  • 当你复制上面的代码或者当你使用你的 pastebin 中的数据时?您可以检查您的请求标头以检查您的请求负载吗?
  • 我忘了重新加载客户端代码 :P 我想现在可以通过了,谢谢!然而,物体似乎有点奇怪。例如,我将如何访问 app_id 在下面? Array([permutation] => Array([permutation_id] => 66) [apps] => [{"app_id": 0, "app_name": "CvP"}])
  • 上述问题似乎很愚蠢,但是当我执行 $data['apps'][0]['app_id'] 时,我不断收到“PHP 警告:非法字符串偏移 'app_id'”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
相关资源
最近更新 更多