PHP json_encode函数有坑?重构老项目被它狠狠打脸!

最近在重构一个老项目,用PHP给前端提供API接口。本来以为json_encode这种基础函数能有什么幺蛾子,结果被现实狠狠打脸。今天就来聊聊这个看似简单实则暗藏杀机的函数。

先来个最简单的例子:

$data = ['name' => '张三', 'age' => 25];

echo json_encode($data);

输出看起来很美:{"name":"张三","age":25}。这时候你觉得这玩意太简单了,然后就开始作死了。

中文编码的坑

第一个坑来得猝不及防。当我把数据库里的中文数据拿出来编码时,突然发现json里中文变成了"\u5f20\u4e09"这种unicode编码。查了手册才发现要加JSON_UNESCAPED_UNICODE参数:

echo json_encode($data, JSON_UNESCAPED_UNICODE);

这还没完,如果你的PHP版本小于5.4,这个参数还不支持,这时候你就得自己写个函数递归处理数组了。

你以为数字类型总安全了?来试试这个:

$data = ['price' => 8.10];

输出居然是{"price":8.99996}!这是因为浮点数精度问题。解决方案要么用字符串表示金额,要么用number_format处理:

$data['price'] = number_format($data['price'], 2, '.', '');

循环引用的悲剧

有一天我遇到了一个神秘错误:"Recursion detected"。查了半天发现是对象之间互相引用:

class A { public $b; }

$a = new A;

$b = new B;

$a->b = $b;

$b->a = $a;

json_encode($a); // 直接爆炸

这时候要么用JSON_PARTIAL_OUTPUT_ON_ERROR参数(PHP7.3+),要么就得手动清理对象引用。

大整数的忧伤

处理ID的时候又踩坑了。JavaScript的Number类型只能安全表示53位整数,而PHP的整数可以很大:

$data = ['id' => 234567890];

前端拿到的是234567000,最后几位被吃了。解决方案是强制转为字符串:

日期时间的烦恼

数据库里的datetime字段直接json_encode会变成字符串,前端还得再解析。其实可以这样处理:

$data = ['create_time' => new DateTime];

echo json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR); // 不行!

最后还是得手动格式化:

$data['create_time'] = $data['create_time']->format(DateTime::ATOM);

二进制数据的尴尬

尝试把图片数据编码成JSON?别闹了:

$data = ['image' => file_get_contents('test.jpg')];

echo json_encode($data); // 可能报错

正确的做法是base64编码:

$data['image'] = base64_encode($data['image']);

深度限制的坑

默认情况下json_encode只能处理512层嵌套的数据。如果你的数据结构很深:

$data = [];

$temp = &$data;

for ($i = 0; $i < 600; $i++) {

$temp['child'] = [];

$temp = &$temp['child'];

}

json_encode($data); // 返回false

这时候要么重构数据结构,要么...还是重构数据结构。

性能优化的思考

在大数据量下,json_encode可能成为性能瓶颈。我曾经处理过一个包含10万条记录的数组,编码耗时2秒多。解决方案:

1. 分批处理

2. 考虑使用MessagePack等替代方案

3. 缓存编码结果

特殊字符的麻烦

当数据里包含特殊字符时:

$data = ['html' => '

test
'];

echo json_encode($data); // 自动转义

如果不想转义,可以组合使用参数:

echo json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

最后来个实用函数收尾,这是我项目中实际使用的:

function safe_json_encode($value, $options = 0, $depth = 512) {

$encoded = json_encode($value, $options, $depth);

if ($encoded === false && $value && json_last_error() == JSON_ERROR_UTF8) {

}

return $encoded;

}

function utf8ize($mixed) {

if (is_array($mixed)) {

foreach ($mixed as $key => $value) {

$mixed[$key] = utf8ize($value);

}

} elseif (is_string($mixed)) {

return mb_convert_encoding($mixed, "UTF-8", "UTF-8");

}

return $mixed;

}

这个函数解决了大多数编码问题,但记住:没有银弹。在PHP里处理JSON,永远要保持警惕,因为说不定什么时候就会冒出个新坑等着你。

内容概要:文章基于4A架构(业务架构、应用架构、数据架构、技术架构),对SAP的成本中心和利润中心进行了详细对比分析。业务架构上,成本中心是成本控制的责任单元,负责成本归集与控制,而利润中心是利润创造的独立实体,负责收入、成本和利润的核算。应用架构方面,两者都依托于SAP的CO模块,但功能有所区分,如成本中心侧重于成本要素归集和预算管理,利润中心则关注内部交易核算和获利能力分析。数据架构中,成本中心与利润中心存在多对一的关系,交易数据通过成本归集、分摊和利润计算流程联动。技术架构依赖SAP S/4HANA的内存计算和ABAP技术,支持实时核算与跨系统集成。总结来看,成本中心和利润中心在4A架构下相互关联,共同为企业提供精细化管理和决策支持。 适合人群:从事企业财务管理、成本控制或利润核算的专业人员,以及对SAP系统有一定了解的企业信息化管理人员。 使用场景及目标:①帮助企业理解成本中心和利润中心在4A架构下的运作机制;②指导企业在实施SAP系统时合理配置成本中心和利润中心,优化业务流程;③提升企业对成本和利润的精细化管理水平,支持业务决策。 其他说明:文章不仅阐述了理论概念,还提供了具体的应用场景和技术实现方式,有助于读者全面理解并应用于实际工作中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值