为什么json_encode会返回一个空字符串

Mat*_*ler 98 php json

我有一个简单的PHP结构,有3个嵌套数组.

我没有使用特定的对象,我自己构建了带有2个嵌套循环的数组.

这是我想要转换为Json的数组的var_dump示例.

array (size=2)
  'tram B' => 
    array (size=2)
      0 => 
        array (size=3)
          'name' => string 'Ile Verte' (length=9)
          'distance' => int 298
          'stationID' => int 762
      1 => 
        array (size=3)
          'name' => string 'La Tronche Hôpital' (length=18)
          'distance' => int 425
          'stationID' => int 771
  16 => 
    array (size=4)
      0 => 
        array (size=3)
          'name' => string 'Bastille' (length=8)
          'distance' => int 531
          'stationID' => int 397
      1 => 
        array (size=3)
          'name' => string 'Xavier Jouvin' (length=13)
          'distance' => int 589
          'stationID' => int 438
Run Code Online (Sandbox Code Playgroud)

在另一个脚本中,我有一个类似的结构,json_encode工作正常.所以我不明白为什么json_encode不在这里工作.

编辑:编码似乎有问题.当mb_detect_encoding返回ASCII,该json_encode作品但当它返回UTF8,它不工作了.

Edit2:json_last_error()返回JSON_ERROR_UTF8表示:格式错误的UTF-8字符,可能编码错误.

Mat*_*ler 240

经过2个小时的挖掘(参见编辑)

我发现了以下内容:

  • 在我的情况下,这是一个编码问题
  • mb_detect_encoding 返回可能是一个错误的响应,一些字符串可能不是UTF-8
  • 使用utf8_encode()那些字符串解决了我的问题.

这是一个递归函数,可以强制转换为UTF-8数组中包含的所有字符串:

function utf8ize($d) {
    if (is_array($d)) {
        foreach ($d as $k => $v) {
            $d[$k] = utf8ize($v);
        }
    } else if (is_string ($d)) {
        return utf8_encode($d);
    }
    return $d;
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

echo json_encode(utf8ize($data));
Run Code Online (Sandbox Code Playgroud)

  • 我现在想给你一个巨大的拥抱<33 (12认同)
  • 感谢您的解决方案......但是,一方面注意:如果(is_string($ d)){`;将`} else {`更改为`} else.否则你将把所有东西都改成字符串(例如`INT`将成为'STRING`). (3认同)
  • 如果从数据库读取只是使用, $conn-&gt;set_charset("utf8"); (3认同)
  • 你刚救了我的命.在我找到这个功能之前,我即将结束一切!谢谢. (2认同)
  • WTF!感谢您分享您的解决方案.我可以看到,这需要花费很多时间才能弄明白,我很感激你这样做并分享. (2认同)

Ada*_*ela 35

Matthieu Riegler提出了非常好的解决方案,但我不得不稍微修改它以处理对象:

function utf8ize($d) {
    if (is_array($d)) 
        foreach ($d as $k => $v) 
            $d[$k] = utf8ize($v);

     else if(is_object($d))
        foreach ($d as $k => $v) 
            $d->$k = utf8ize($v);

     else 
        return utf8_encode($d);

    return $d;
}
Run Code Online (Sandbox Code Playgroud)

还有一点需要注意:json_last_error()可能有助于调试json_encode()/ json_encode()函数.

  • @UweKeim根据PHP文档"elseif,否则只有在使用花括号时才会被认为是完全相同的"这意味着它们是等价的,只要你不使用冒号表示法,例如`if():elseif:` (2认同)

小智 24

对我来说,这个问题的答案是在我的PDO连接中设置charset = utf8.

例如:$dbo = new PDO('mysql:host=localhost;dbname=yourdb;charset=utf8', $username, $password);

  • 或者在mysqli函数中:mysqli_set_charset($ connection,"utf8"); (2认同)
  • 请在最近的 MySQL 版本中使用``utf8mb4``。`utf8` 已过时。 (2认同)

Ale*_*lex 8

Adam Bubela也提出了非常好的解决方案,帮助我解决了我的问题,这里是简化的功能:

function utf8ize($d)
{ 
    if (is_array($d) || is_object($d))
        foreach ($d as &$v) $v = utf8ize($v);
    else
        return utf8_encode($d);

    return $d;
}
Run Code Online (Sandbox Code Playgroud)


Vse*_*sky 6

我在PHP 5.6上有完全相同的问题。我在Windows 7上使用Open Server + Nginx。所有字符集均设置为UTF-8。理论上,根据官方文件,标志

JSON_UNESCAPED_UNICODE

要解决这个问题。不幸的是,这不是我的情况。我不知道为什么。上面的所有代码片段都不能解决我的问题,因此我找到了自己的实现。我认为它可以帮助别人。至少,俄语字母通过了测试。

function utf8ize($d) {
    if (is_array($d) || is_object($d)) {
        foreach ($d as &$v) $v = utf8ize($v);
    } else {
        $enc   = mb_detect_encoding($d);

        $value = iconv($enc, 'UTF-8', $d);
        return $value;
    }

    return $d;
}
Run Code Online (Sandbox Code Playgroud)


Kho*_*elo 5

这个接受的答案有效。但是,如果您从 MySQL 获取数据(就像我一样),有一种更简单的方法。

打开数据库后,在查询之前,您可以使用 mysqli 设置字符集,如下所示:

/* change character set to utf8 | Procedural*/
if (!mysqli_set_charset($link, "utf8")) {
    printf("Error loading character set utf8: %s\n", mysqli_error($link));
    exit();
}
Run Code Online (Sandbox Code Playgroud)

或者

/* change character set to utf8 | Object Oriented*/
if (!$mysqli->set_charset("utf8")) {
        printf("Error loading character set utf8: %s\n", $mysqli->error);
        exit();
 }
Run Code Online (Sandbox Code Playgroud)

链接:http : //php.net/manual/en/mysqli.set-charset.php


Sha*_*e N 5

我在运行旧版本 PHP (5.2) 的服务器上遇到了这个问题。我使用的是 JSON_FORCE_OBJECT 标志,显然直到 5.3 才支持它

因此,如果您正在使用该标志,请务必检查您的版本!

解决方法似乎只是在编码之前强制转换为对象,例如:

json_encode((object)$myvar);
Run Code Online (Sandbox Code Playgroud)