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

时间:2013-10-14 13:24:14

标签: 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

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

编辑:编码似乎有问题。当mb_detect_encoding返回ASCII时,json_encode可以正常工作,但当它返回UTF8时,它不再起作用。

Edit2:json_last_error()返回JSON_ERROR_UTF8,表示:Malformed UTF-8 characters, possibly incorrectly encoded

13 个答案:

答案 0 :(得分:223)

经过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;
}

使用它就像这样:

echo json_encode(utf8ize($data));

注意:utf8_encode()根据文档将ISO-8859-1字符串编码为UTF-8,因此如果您不确定输入编码iconv()mb_convert_encoding()可能是更好的选项在评论和其他解决方案中注明。

答案 1 :(得分:34)

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;
}

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

答案 2 :(得分:23)

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

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

答案 3 :(得分:7)

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

URL:

答案 4 :(得分:5)

我在PHP 5.6上遇到了完全相同的问题。 我在Windows 7上使用Open Server + Nginx。所有字符集都设置为UTF-8。 理论上,根据official documentation,标志

  

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;
}

答案 5 :(得分:4)

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

才支持

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

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

json_encode((object)$myvar);

答案 6 :(得分:3)

mb_detect_encoding的返回可能不正确:

$data = iconv('UTF-8', 'ISO-8859-1', 'La Tronche Hôpital');
var_dump(
    mb_detect_encoding($data),
    mb_detect_encoding($data, array('ISO-8859-1', 'UTF-8'))
);

根据默认检测顺序,上述内容可能会返回不同的结果,因此错误地将编码报告为UTF-8。 (Here's a larger example。)

您的数据很可能未编码为UTF-8,因此json_encode正在返回false。您应该在JSON编码之前将字符串转换为UTF-8:

$fromEncoding = 'ISO-8859-1'; // This depends on the data

array_walk_recursive($array, function (&$value, $key, $fromEncoding) {
    if (is_string($value)) {
        $value = iconv($fromEncoding, 'UTF-8', $value);
    }
}, $fromEncoding);

答案 7 :(得分:3)

这个被接受的答案有效。但是如果你从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();
}

OR

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

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

答案 8 :(得分:2)

在那些字符串上使用utf8_encode()解决了我的问题。

答案 9 :(得分:2)

我从ob_get_clean()获取数据并遇到同样的问题,但上述解决方案对我不起作用。在我的情况下解决方案是这个,也许它会帮助某人。

$var = mb_convert_encoding($var, 'UTF-8');

答案 10 :(得分:1)

我改进了Adam Bubela的答案。 当{和}未关闭块时,我只是讨厌它。 它更清洁,你不会引入错误或者我过去使用Perl的错误:)

<?php

class App_Updater_String_Util {    
    /**
     * Usage: App_Updater_String_Util::utf8_encode( $data );
     *
     * @param mixed $d
     * @return mixed
     * @see http://stackoverflow.com/questions/19361282/why-would-json-encode-returns-an-empty-string
     */
    public static function utf8_encode($d) {
        if (is_array($d)) {
            foreach ($d as $k => $v) {
                $d[$k] = self::utf8_encode($v);
            }
        } elseif (is_object($d)) {
            foreach ($d as $k => $v) {
                $d->$k = self::utf8_encode($v);
            }
        } elseif (is_scalar($d)) {
            $d = utf8_encode($d);
        }

        return $d;
    }
}

?>

答案 11 :(得分:0)

如果从数据库中获取此数据,则从数据库获取参数时请使用mysqli_set_charset($connection, "utf8");进行连接

答案 12 :(得分:0)

有时会出现此问题-您没有通过标头访问控制。

就我而言,如果我在json_encode之前添加了任何回显。它正在显示结果,否则将出现空白页。

我添加了

header('Access-Control-Allow-Origin: *'); 

我的问题解决了。

相关问题