PHP json中的Malformed UTF-8 characters问题

json_encode函数原型:

string json_encode (mixed $value[, int $options = 0 [, int $depth = 512 ]])

成功则返回 JSON 编码的 string 或者在失败时返回 FALSE 。

一般情形下,json嵌套层级太深这种失败是罕见,但是又相对比较容易识别的;另外一种错误,是关于utf-8编码的,则情形相对比较复杂;

$wrong_encoding = urldecode("%CD");
$arr = [$wrong_encoding,["123"=>["234"=>$wrong_encoding]]];
var_dump(json_encode($arr));//bool(false)

这个例子是利用urlcode不检查编码,生成了不合法的utf-8字符串;

多字节残缺的UTF-8编码的二进制数据会影响到字符串的边界;

echo ord(urldecode("%CD"));//205

205的二进制形式为:11001101 [UTF-8](http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html)

UTF-8编码规则下,这应该是一个双字节字符,明显可以看到,这里是一个单字节字符;

下面则是处理方式:

function json_encode_with_utf8_detect($arr,$replace = null){
    $json = json_encode($arr);
    //没有utf-8编码问题的,直接返回encode之后内容
    if($json !== false || json_last_error() != JSON_ERROR_UTF8){
        return $json;
    }
    array_walk_recursive($arr,function (&$value)use($replace){
        if(is_string($value)){
            $value = mb_check_encoding($value,'UTF-8') ? $value : $replace;
        }
    });
    return json_encode($arr);
}

在检测到数组内部存在某些错误编码的字符串,用$replace代替改内容,然后返回对应的json数据

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

web后端

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏河湾欢儿的专栏

第一节预解释、作用域、this原理

10620
来自专栏everhad

札记:Java异常处理

异常概述 程序在运行中总会面临一些“意外”情况,良好的代码需要对它们进行预防和处理。大致来说,这些意外情况分三类: 交互输入 用户以非预期的方式使用程序,比如...

26080
来自专栏程序员同行者

Python pass语句作用与用法

13720
来自专栏用户2442861的专栏

Java中Synchronized的用法

原文:http://blog.csdn.net/luoweifu/article/details/46613015 作者:luoweifu 转载请标名...

7510
来自专栏Jerry的SAP技术分享

使用javap深入理解Java整型常量和整型变量的区别

下面我们就用javap将.class文件反编译出来然后深入研究Java里整型变量和整型常量的区别。

15530
来自专栏magicsoar

C++获取private的变量-偷走private

private提供了对数据的封装,使得private成员只能被类自身的成员函数以及类的友元访问,其他的函数或者类想要访问private成员只能通过该类所提供的s...

188100
来自专栏决胜机器学习

设计模式专题(十六)——迭代器模式

设计模式专题(十六)——迭代器模式 (原创内容,转载请注明来源,谢谢) 一、概述 迭代器模式(Iterator)提供一种方法,顺序访问一个聚合对象中的每个元素...

37380
来自专栏前端知识分享

第193天:js---Math+Error+Number+Object总结

8320
来自专栏冰霜之地

从 JavaScript 作用域说开去

在电脑程序设计中,作用域(scope,或译作有效范围)是名字(name)与实体(entity)的绑定(binding)保持有效的那部分计算机程序。不同的编程语言...

10730
来自专栏C/C++基础

C++inline函数简介

inline函数是由inline关键字来定义,引入inline函数的主要原因是用它替代C中复杂易错不易维护的宏函数。

23420

扫码关注云+社区

领取腾讯云代金券