PHP函数记录-trim导致的编码异常

博客详细描述了在使用Laravel开发业务接口时遇到的500错误,问题根源在于trim函数处理多字节字符(如中文的¥)时出现异常。作者通过分析字节和ASCII码,发现trim会误删中文字符的一部分字节,导致乱码。解决方案是使用多字节安全的mb_trim函数来替代。博客内容涵盖了编码、UTF-8、PHP字符串处理以及错误排查技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近写业务接口报500,排查发现是编码问题导致 laravel response异常。

起初以为是DB编码导致,排除后发现了是代码中的trim导致的

//给到前端纯洁的数据  之前有拼接¥%等标识
public function normalField($data)
{
        $charlist = '%¥';
        foreach ($data as $tag => &$item) {
                           array_walk_recursive($item, function (&$value) use ($charlist) {
                    if (is_scalar($value)) {
                        $value = trim($value, $charlist);
                    }
                });
            break;
        }

官方文档

trim不是多字节的,比如中文相关的 utf8大部分是三个字节
这里用到了 ¥ 和字符串 包含了运营
即 trim(’运营’, ‘%¥’)

        $trim = '¥ 营';
        for ($i = 0; $i< strlen($trim);$i++){
            echo sprintf("字节%s对应的asc码%d,16进制:%s", $trim[$i],ord($trim[$i]), base_convert(ord($trim[$i]), 10, 16)) .PHP_EOL;
        }
字节�对应的asc码239,16进制:ef
字节�对应的asc码191,16进制:bf
字节�对应的asc码165,16进制:a5
字节 对应的asc码32,16进制:20
字节�对应的asc码232,16进制:e8
字节�对应的asc码144,16进制:90
字节�对应的asc码165,16进制:a5

发现问题 尾字节 都是a5 trim会把误伤 营的a5

¥对应的三个字节是 ef  bf  a5
营 对应的三个字节是 e8 90 a5

文档有提示作用机制

Note: Possible gotcha: removing middle characters
Because trim() trims characters from the beginning and end of a string, it may be 
confusing when characters are (or are not) removed from the middle. trim('abc', 'bad') 
removes both 'a' and 'b' because it trims 'a' thus moving 'b' to the beginning to also be 
trimmed. So, this is why it "works" whereas trim('abc', 'b') seemingly does not.

解决方式

  1. 自定义 mb_trim

参考

PHP字符串与字节转换示例
PHP trim乱码原因

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值