【问题标题】:json_decode syntax error from valid json [closed]来自有效 json 的 json_decode 语法错误
【发布时间】:2015-02-27 10:29:10
【问题描述】:

我有这个简单的 JSON 字符串:

{"type_voie":"ALL","indice_repetition":"B","num_voie":"1","nom_voie":"Azrty","infos_voie":"Zzz","distribution_speciale":"","cp":"34230","ville":"PLAISSAN","bureau_distributeur":""}

我从我的 utf8 数据库中获取。

当我将它传递给json_decode($json, true) 时,结果为 NULL,json_last_error() 给我 4 (JSON_ERROR_SYNTAX)

如果我做 mb_detect_encoding,我可以看到字符串是 ASCII,但我只在所有地方使用 UTF-8。

字符串最初是通过 AJAX 查询插入到数据库中的。我从一个用 jQuery 函数 serialize() 序列化的表单中得到了日期。

我在我的项目中经常这样做,从来没有遇到过这样的问题。

我尝试使用 iconv、mb_convert_encoding 或 ut8_encode 强制 UTF8,但没有任何改变。

我也尝试使用html_entity_decode(),因为有时 PDO 会替换引号,但结果相同。

编辑:

我的天啊。 对不起。

由于某些原因,在我获得 json 的那一刻和我将它发送到解析器的那一刻之间连接了一个
。 只有PEBKAC....

我很惭愧。

将很快删除此帖子

【问题讨论】:

  • 一定有你没有抄袭的角色。当我将该字符串粘贴到我的脚本中时,它工作正常。
  • 这是来自 var_dump() 的完整字符串
  • 你试过json_decode( utf8_encode( $json ) )吗?
  • 是的,还有 iconv()...同样的结果
  • 你能将 var_dump 报告的字符串长度与字符串的实际长度进行比较(通过计算屏幕上的字符吗?)?那里可能有不可打印的字符。它将解释为什么复制字符串使其工作,因为不可打印的字符也不能被复制。

标签: php json


【解决方案1】:

在使用json_decode()之前,您必须使用 UTF-8 对源代码进行编码
试试这个代码:

$json = mb_convert_encoding($json, "UTF-8");
var_dump(json_decode($json, true));

【讨论】:

  • 已经尝试过 mb_convert_encoding、utf8_encode、iconv... 这些都不起作用。我开始认为这可能是一个 php 错误
  • 好的,最后一次机会。首先尝试使用 mb_convert_encoding($json, "UTF-8", "UTF-8"); (有时这个函数在没有第三个参数的情况下出错)。否则尝试: mb_convert_encoding($json, "UTF-8", "ASCII");在 sof 中也有一篇文章将编码从 ASCII 转换为 UTF-8 stackoverflow.com/questions/4983989/…
  • @garek007 欢迎!
【解决方案2】:

你的有效 json 可能像这样在你的数组中添加 [] 然后生成 json

[{"type_voie":"ALL","indice_repetition":"B","num_voie":"1","nom_voie":"Azrty","infos_voie":"Zzz","distribution_speciale":"","cp":"34230","ville":"PLAISSAN","bureau_distributeur":""}]

【讨论】:

  • 将 json 数据转换为类似数组的方式没有任何帮助。
【解决方案3】:

我们在 cmets 中发现字符串中有不可见的字符,请考虑运行这段代码。它应该显示字符串中的每个字符,它的 ascii 值和打印版本。

里面应该有几个不打印任何东西的字符;这些是阻止您对字符串进行 json_encoding 的原因。我看不到 why 它们在字符串中,这与您的数据库和您发布到其中的数据有关,但至少您会知道 哪里 问题是。

很可能它们包含在某处插入的数据中,这意味着您可能在某处有一段代码在其输入中添加了一些不可打印的内容。

您可以在导出时删除它们,但最好找出哪些代码添加它们并将它们从数据库中删除。否则,他们将来会继续打扰您。 (正如你在这一点上看到的那样,即使像 strlen() 这样简单的东西也会因为这些字符而无法正常工作)

for( $i = 0 ; $i < mb_strlen($string) ; $i++ ) {
  echo 'pos: ' . $i . ' | ord: ' . ord( $string[$i] ) . ' | char: ' . $string[$i] . '<br />';
}

【讨论】:

  • 我接受这个答案是因为你把我放在了正确的位置,但实际上它不仅是一个不可见的字符,而且是一个完整的 HTML 标记......
  • 哈。是的,这些在您的浏览器中也是不可见的。一秒钟都没想到。很高兴听到你现在把它修好了!
  • 效果很好.. 尝试了所有其他解决方案并花费数小时调试它。
  • 对于使用 API 的人,您无法编辑 API 为您提供的内容:如果您使用 file_get_contents 获取 API 结果,并且打印出 似乎 就像格式正确的String,将字符串检查为 HTML。它应该向您显示任何隐藏的字符。然后您可以使用offset 参数来修剪这些字符。阅读有关偏移量的更多信息here
【解决方案4】:

正如人们在之前的答案中指出的那样,json 中可能存在不可打印的字符,这意味着它们应该在调用 json_decode 之前被删除。

这样做的一种方法是:

$json = preg_replace('/[[:^print:]]/', '', $json);

我并不是说这是最好的解决方案,但到目前为止我发现的唯一一个对我有用。

【讨论】:

    猜你喜欢
    • 2019-08-24
    • 1970-01-01
    • 2011-11-29
    • 2016-10-02
    • 2013-08-19
    • 2013-08-26
    • 2012-10-16
    • 1970-01-01
    • 2017-07-05
    相关资源
    最近更新 更多