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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19361282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 19:21:37  来源:igfitidea点击:

Why would json_encode return an empty string

phpjson

提问by Matthieu Riegler

I have a simple php structure with 3 nested arrays.

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

I do not use particular objects and I build myself the arrays with 2 nested loops.

我不使用特定对象,而是使用 2 个嵌套循环为自己构建数组。

Here is a sample of the var_dump of the array I want to convert to Json.

这是我要转换为 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

In another script I have a similar structure and json_encodeworks fine. So I don't understand why json_encodewon't work here.

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

Edit : there seems to be a problem with the encoding. When mb_detect_encodingreturns ASCII, the json_encodeworks but when it returns UTF8, it doesn't work anymore.

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

Edit2 : json_last_error()returns JSON_ERROR_UTF8which means : Malformed UTF-8 characters, possibly incorrectly encoded.

Edit2:json_last_error()返回JSON_ERROR_UTF8这意味着:格式错误的 UTF-8 字符,可能编码不正确

回答by Matthieu Riegler

Well after 2 hours of digging (cf Edits)

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

I found out following :

我发现以下内容:

  • In my case it's a encoding problem
  • mb_detect_encodingreturns probably a faulty response, some strings were probably not UTF-8
  • using utf8_encode()on those string solved my problem, but see note below
  • 就我而言,这是一个编码问题
  • mb_detect_encoding可能返回错误响应,某些字符串可能不是 UTF-8
  • utf8_encode()在这些字符串上使用解决了我的问题,但请参阅下面的注释

Here is a recursive function that can force convert to UTF-8 all the strings contained in an array:

这是一个递归函数,可以强制将数组中包含的所有字符串转换为 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;
}

Use it simply like this:

像这样简单地使用它:

echo json_encode(utf8ize($data));

Note: utf8_encode()encodes ISO-8859-1 string to UTF-8 as per the docs so if you are unsure of the input encoding iconv()or mb_convert_encoding()may be better options as noted in comments and other solutions.

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

回答by Adam Bubela

Matthieu Riegler presented really good solution however I had to slightly modify it to handle objects too:

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

One more note: json_last_error()may be helpful in debugging json_encode()/json_encode() functions.

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

回答by fayd

For me, the answer to this problem was setting charset=utf8in my PDO connection.

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

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

回答by Alex

Adam Bubela also presented really good solution who helped me solved my problem, and here is the simplified function :

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

回答by Vsevolod Azovsky

I have exactly the same problem on PHP 5.6. I use Open Server+ Nginx on Windows 7. All charsets are set to UTF-8. In theory, according the official documentation, flag

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

JSON_UNESCAPED_UNICODE

JSON_UNESCAPED_UNICODE

should solve this. Unfortunately this is not my case. I do not know, why. All snippets above do not solve my problem, thus I have found my own implementation. I believe it could help someone. At least, Russian letters pass the test.

应该解决这个问题。不幸的是,这不是我的情况。我不知道为什么。上面的所有片段都没有解决我的问题,因此我找到了自己的实现。我相信它可以帮助某人。至少,俄文字母通过了测试。

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

回答by Kholofelo

This accepted answer works. But in case you are getting your data from MySQL (as I was) there is an easier way.

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

Once you open you database, before you query you can set the character set using mysqli as follows:

打开数据库后,在查询之前,您可以使用 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

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

回答by Shane N

I ran into this issue on a server running an older version of PHP (5.2). I was using the JSON_FORCE_OBJECT flag, and apparently that isn't supported until 5.3

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

So if you're using that flag be sure to check your version!

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

A workaround appears to be just casting to an object before encoding, like:

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

json_encode((object)$myvar);

回答by cmbuckley

The return of mb_detect_encodingmay not be correct:

的返回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'))
);

Depending on the default detection order, the above may return different results, so the encoding is falsely being reported as UTF-8. (Here's a larger example.)

根据默认的检测顺序,上面可能会返回不同的结果,因此编码被错误地报告为 UTF-8。(这是一个更大的例子。)

It is likely that your data is not encoded as UTF-8, so json_encodeis returning false. You should look at converting your strings to UTF-8 before JSON-encoding:

您的数据可能未编码为 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);

回答by zdeniiik

I was getting data from ob_get_clean() and had the same problem, but above solutions don't work for me. In my case solution was this, maybe it will help somebody.

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

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

回答by mobizen

using utf8_encode() on those string solved my problem.

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