[英]Why would json_encode return an empty string
我有一个带有 3 个嵌套数组的简单 php 结构。
我不使用特定对象,而是使用 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
这意味着:格式错误的 UTF-8 字符,可能编码不正确。
经过 2 小时的挖掘(参见编辑)
我发现以下内容:
mb_detect_encoding
可能返回错误响应,某些字符串可能不是 UTF-8utf8_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()可能是更好的选择,如注释和其他解决方案中所述。
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() 函数。
对我来说,这个问题的答案是在我的 PDO 连接中设置charset=utf8
。
$dbo = new PDO('mysql:host=localhost;dbname=yourdb;charset=utf8', $username, $password);
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;
}
我在 PHP 5.6 上有完全相同的问题。 我在 Windows 7 上使用Open Server + Nginx。所有字符集都设置为 UTF-8。 理论上,根据官方文档,flag
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;
}
这个接受的答案有效。 但是,如果您从 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();
}
我在运行旧版本 PHP (5.2) 的服务器上遇到了这个问题。 我使用的是 JSON_FORCE_OBJECT 标志,显然直到 5.3 才支持
因此,如果您正在使用该标志,请务必检查您的版本!
解决方法似乎只是在编码之前转换为对象,例如:
json_encode((object)$myvar);
我正在从 ob_get_clean() 获取数据并遇到同样的问题,但上述解决方案对我不起作用。 在我的情况下,解决方案是这样的,也许它会帮助某人。
$var = mb_convert_encoding($var, 'UTF-8');
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 编码之前,您应该考虑将字符串转换为 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);
我改进了 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;
}
}
?>
在这些字符串上使用 utf8_encode() 解决了我的问题。
如果您从数据库获取此数据,请使用mysqli_set_charset($connection, "utf8");
从数据库中获取参数时的连接
这个问题有时会出现 - 您没有传递标头访问控制。
就我而言,如果我在 json_encode 之前添加了任何回声。 它正在显示结果,否则空白页即将到来。
我加了
header('Access-Control-Allow-Origin: *');
我的问题解决了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.