PHP+trim乱码,PHP的trim和preg_replace导致乱码的问题及解决

trim问题发现

某天,线上展示的数据,发现多了问号,一排查,上游数据里多了0xC2和0xA0,百度查了一下,说是UTF8格式的空格,对应 网页里的 这个东东。

ok,问题找到了,简单对数据做一个trim就好了嘛,于是代码改成:

$name = trim($name, chr(0xc2) . chr(0xa0));

嗯,这么简单的代码还测试啥,上线吧!

结果,当天就有负责审核的同学找来了,怎么数据都会少字啊,比如漫画变成了漫,画字不见了……

var_dump(trim('平安普惠', chr(0xc2) . chr(0xa0)));

// 打印结果是 平安普,少了一个惠字

查了一下资料,原来php默认不能正确处理多字节字符,比如中文,如果要处理中文,要用mb_开头的函数,参考:http://php.net/manual/zh/ref.mbstring.php

可是,问题来了,没有 mb_trim这样的函数啊啊啊!

还好,上面的页面里也给了解决方案,用正则+utf8模式代替,嗯,php官方参考页面有其它用户提供了解决方案:

function mb_trim($string, $trim_chars = '\s'){

return preg_replace('/^['.$trim_chars.']*(?U)(.*)['.$trim_chars.']*$/u', '\\1',$string);

}

好吧,我稍微优化了一下,变成:

function mb_trim($string){

return preg_replace('/(^\s*)|(\s*$)/u', '', $string);

}

这回不能盲目上线了,对库中400万的数据遍历测试了一轮,果然出问题了,

$str = '破千魂';

$str2 = mb_trim($str);

var_dump($str2); // str2变成了NULL

查了半天资料,没有结论,后面想到\s*,即使没有空格也会进行替换,效率不好,改成\s+,结果就ok了,汗,最终的mb_trim函数定义如下:

function mb_trim($string){

// u模式符表示 字符串被当成 UTF-8处理

return preg_replace('/(^\s+)|(\s+$)/u', '', $string);

}

后语,为啥\s*会出错呢?偶然发现在php5.2版本上,\s*也能正常工作,hhvm下也是正常的, 再看我出问题的php,是5.4.33,赶紧去官网重新下载了一个5.4.45(php5.4最后一个版本),编译并测试后,发现结果也是正常的,重新下载5.4.33编译,问题依旧, 至此,确认那是php5.4.33的一个bug了,不过最后那个版本的mb_trim还是能正常工作的。 记录下来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值