为什么会json_encode返回一个空string

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

我不使用特定的对象,我build立了自己的数组与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时,它不再工作。

编辑2: json_last_error()返回JSON_ERROR_UTF8这意味着: 格式错误的UTF-8字符,可能错误地编码 。

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

我发现如下:

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

这是一个recursion函数,可以强制转换为UTF-8数组中包含的所有string:

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

Matthieu Riegler提出了非常好的解决scheme,但我不得不略微修改它来处理对象:

 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()可能对debuggingjson_encode()/ json_encode()函数有帮助。

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

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

亚当Bubela也提出了很好的解决scheme谁帮我解决了我的问题,这里是简化的function:

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

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。 ( 这是一个更大的例子 。)

很可能您的数据不是以UTF-8编码,所以json_encode返回false 。 在JSON编码之前,您应该将您的string转换为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); 

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

要么

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

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

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

所以,如果你使用的是国旗,一定要检查你的版本!

解决方法似乎只是在编码之前将其转换为对象,如下所示:

 json_encode((object)$myvar); 

对这些string使用utf8_encode()解决了我的问题。

我已经改进了Adam Bubela的回答。 我只是恨,当块没有被{和}closures。 它更干净,你不会引入错误,也可能是我过去使用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; } } ?> 

我从ob_get_clean()获取数据,并有同样的问题,但上述解决scheme不适合我。 在我的情况下,解决scheme是这样的,也许它会帮助别人。

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