说明
在使用 PHP 的时候,可能会遇到编解码的错误。这里面的编解码包括 BASE64、json_encode、json_decode 等。
下面是使用 YII2 框架,一个请求在返回数据的数据时候,出现的错误:
Malformed UTF-8 characters, possibly incorrectly encoded.
问题和解决方案
出现上面的问题,可能有下面几种情况:
字符集不统一
编解码前后使用的字符集不一致,导致编码成一种字符集,解码的时候是另一种字符集。要检查编解码前后的字符集是否一致。
可以使用下面的一些函数进行检查。
# 设置内部字符编码为 UTF-8
mb_internal_encoding("UTF-8");
# 显示当前的内部字符编码
echo mb_internal_encoding();
# 检测 HTTP 输入字符编码
mb_http_input()
# 设置/获取 字符编码的检测顺序
mb_detect_order()
# 设置/获取 HTTP 输出字符编码
mb_http_output()
# 设置/获取多字节正则表达式的字符编码
mb_regex_encoding()
全局设置指定的字符集
方法1:代码中设置成 UTF-8 字符集:
mb_internal_encoding("UTF-8")
方法2:在 php.ini 中设置
mbstring.internal_encoding = UTF-8
字符集转换
将指定字符串从 encoding1 字符集。
mb_convert_encoding($str, $encoding1, $encoding2);
参数说明
encoding1:目标编码,如utf-8,gbk,大小写均可;
$encoding2:原编码,如utf-8,gbk,大小写均可。
案例一
$str='你好,世界';
// 编码转换为utf-8
echo mb_convert_encoding($str, "UTF-8");
案例二
$str='你好,世界';
// 已知原编码为GBK,转换为utf-8
echo mb_convert_encoding($str, "UTF-8", "GBK");
案例三
$str='你好,世界';
// 把 GBK,GB2312,BIG5 这几种编码转成 UTF-8 编码。
$content = mb_convert_encoding($str, 'UTF-8', 'GBK,GB2312,BIG5');
案例四
$str='你好,世界';
// 未知原编码,通过auto自动检测后,转换编码为utf-8
echo mb_convert_encoding($str, "UTF-8", "auto");
不可编码的数据
在使用 json 进行编码的时候,编码的数据可能经过 base64 进行解码,但是原数据可能不是 base64 编码的,因此会导致 base64 解码错误,然后再使用 json 进行 json_encode 等编码时,出现上面的错误。
该问题需要检查进入 json_encode 的数据,是否是正常数据,如果操作的数据不是正常字符数据,json_encode 可能会返回空,也可能会返回 true、false 之类的数据,也可能报错。
在 YII2 中,如果返回的是 JSON 格式的数据,框架在执行 Respnose 方法的时候,会调用
BaseJson.php 中的 encode 方法:
BaseJson::encode($str);
如果 $str 数据不是正常数据,此处也会报上面的错误。
所以要检查好 json_encode 的数据是否是正常数据。
{{item.user_info.nickname ? item.user_info.nickname : item.user_name}}
作者 管理员 企业
{{itemf.name}}
{{itemc.user_info.nickname}}
{{itemc.user_name}}
回复 {{itemc.comment_user_info.nickname}}
{{itemf.name}}