【问题标题】:How to json_decode an json array received from JavaScript?如何对从 JavaScript 接收到的 json 数组进行 json_decode?
【发布时间】:2018-06-20 23:27:29
【问题描述】:

我想将 json 字符串编码的数据发送到 PHP 后端。为此,我使用了GET 参数,其中包含 URL 编码的 json 数据,格式如下:["mystring1","mystring2"]

当我现在尝试使用 php 的 json_decode 函数对其进行解码时,它返回 null。此外,使用这个输入字符串,根本不会改变任何东西:{"mykey":["mystring1","mystring2"]}

这是我的完整代码示例:

JavaScript:

var myArr = [];
myArr.push('mystring1');
myArr.push('mystring2');
window.location.href = 'example.com/index.php?myparam=' + encodeURIComponent(JSON.stringify(myArr));

PHP 后端站点:

$jsonStr = filter_input(\INPUT_GET, 'myparam', \FILTER_SANITIZE_STRING);
var_dump($jsonStr);
var_dump(json_decode($jsonStr, true));

第一个var_dump 正确打印json 字符串,第二个返回null。使用 assoc 标志(第二个json_encode 参数)不会改变任何东西。

我期望得到的:

array(2) { [0]=> string(9) "mystring1" [1]=> string(9) "mystring2" }

我实际上得到了什么:

NULL

var_dump for $jsonStr 为我返回以下内容:

string(41) "["mystring1","mystring2"]"

【问题讨论】:

  • 您是否有机会为此使用 POST 并将 JSON 放入请求正文中?然后,您不必对其进行 URI 编码。无论如何,如果 json_decode 什么也没返回,它可能会失败 - 使用这个函数:php.net/manual/en/function.json-last-error-msg.php 找出原因。
  • 如果您需要进一步的帮助,请显示var_dump($jsonStr);的结果
  • 使用上面给出的例子,没有错误:$jsonStr = '{"mykey":["mystring1","mystring2"]}'; var_dump(json_decode($jsonStr, true)); 打印出预期的结果。这可能失败的唯一原因是您没有插入 JSON 字符串。因此,除非我们看到您的 $jsonStr 的真实输出,否则我们无法帮助您。
  • @feeela 是的。但我的意思是,如果你使用json_decode('["mystring1","mystring2"]');,它会产生null
  • @feeela 我怀疑问题是encodeURIComponent(JSON.stringify(myArr)) 导致%5B%22mystring1%22%2C%22mystring2%22%5D 当然不是有效的JSON,所以除非服务器已经解码,否则会有问题。我猜它可以颠倒过来,但使用 POST 并将 JSON 放在正文中会更简单(或者只使用普通的单独查询字符串参数)。

标签: javascript php json


【解决方案1】:

我正在从What does FILTER_SANITIZE_STRING do? 转移一张便条,但该问题中的整个接受的答案解释得更好:

首先 - php_filter_strip。它做的不多,只是将您传递给函数的标志并相应地处理它们。它做了有据可查的事情。

然后我们构造某种地图并调用php_filter_encode_html。更有趣的是:它将诸如“、'、& 和 ASCII 代码低于 32 且高于 127 的字符之类的内容转换为 HTML 实体,因此字符串中的 & 变为 &。再次,它使用标志为此。

然后我们调用php_strip_tags_ex,它只是去除 HTML、XML 和 PHP 标记(根据 /ext/standard/string.c 中的定义)并删除 NULL 字节,就像评论说的那样。

(强调重要部分)。

简而言之,FILTER_SANITIZE_STRING 会破坏你的 JSON,因为它会编码它不应该编码的东西。如果您想验证此输入,请不要使用此过滤器。

这里的答案是不要使用FILTER_SANITIZE_STRING。 验证 JSON 字符串的明智方法是执行 json_decode 并检查它是否为空。

$jsonStr = filter_input(\INPUT_GET, 'myparam'); 
var_dump($jsonStr); 
var_dump(json_decode($jsonStr, true)); 

【讨论】:

  • 非常感谢您的调查! :-)
  • 我强烈建议您在调试时使用 Symphony 的 VarDumper 组件,因为它会逐字显示字符串,而不是将其转储到浏览器窗口中并让浏览器将其呈现为 HTML。
  • 好吧,感谢您的提示,但是在我们的一些普通 php 项目中,不可能将 composer 集成到那里。如果我会遇到同样的问题,我会在未来对它的内容进行二进制比较。我认为这也可能有所帮助。
【解决方案2】:

这里的错误与 JSON 无关,而在于请求使用了编码的 URI 组件。

如果您在 JS 端使用 encodeURIComponent,您还必须在 PHP 端使用 urldecode

<?php
$jsonStr = '%5B%22mystring1%22%2C%22mystring2%22%5D';
var_dump(
    json_decode(urldecode($jsonStr), true)
);

见:http://php.net/manual/en/function.urldecode.php

【讨论】:

  • 不,请参阅上面的评论。它已经在代表字符串中正确编码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多