php 替换 乱码,php中str_replace导致乱码的诡异问题

支付宝内搜索 9155838 即可领现金红包 每天都能领哦

10:19:17

朋友有个站的文章内容有时候会显示乱码,让我给看看。

拿到服务器权限后,我上去一看,php都几百个,觉得有点头大,感觉无从查起,并且我也不想在本地重新布置环境,要下载代码和数据库好麻烦。

就只能在线调试了,改了点东西就可能500了,坑爹的是在php.ini里面打开报错,重启后仍然看不到错误信息,在nginx日志和php日志里面也看不到错误信息,不知服务器配置是怎么设置的,但也不想去研究配置了 -_-||

凭着我三脚猫的功夫经过大半天的排查修改,将近凌晨的时候终于在几十个模块中将问题定位到str_replace函数上面了:

问题出在有一行str_replace是将全角空格替换为半角空格的代码(即下图第9行),将其注释即搞定。

现在将问题现象重新整理重现一下,将无关代码全部剔除,只提取最关键代码,又发现一个新的现象:原文本里面的“场。”经过替换后会变成“常”,这真是有点奇怪,如图:

079501b5fe0ad9a5b798afbe63862d50.png

这时,没出现乱码的原因是我将mb_substr函数删掉了,因为这个时候乱码的问题已经不重要了,一个字变成另一个没替换过的字的问题才更诡异。

经测试任何版本的php都有此奇异现象

简要代码如下(php文件编码为gb2312):

header("Content-type:text/html; charset=gbk");

$arr1='这是心灵博客的一个测试用例,具体请见http://blog.dngz.net/phpstrreplace.htm,今天心灵博客发生了个开心的事,但你不在场。';

$arr1 = textReplace($arr1);

echo $arr1;

function textReplace($str)

{

$str = str_replace(' ','',$str); //屏蔽此行则正常

$str = str_replace('开心','happy',$str);

return $str;

}

php技术大佬帮我看看吧,但愿不是什么php对中文支持不够友好的说法……

2019-11-22 23:00:38 补充:

产生这个问题的原因:

将这几个字的编码转换一下:

场。 常

编码转码后:

%b3%a1 %a1%a3 %a1%a1 %b3%a3

“场”的后半部分和句号的前半部分正好组成全角的%a1%a1被替换为空,然后剩余部分正好组成%b3%a3,正好是“常”的编码。

感谢php大神自由勇给出的解决方法:我有时连续几个月每天PHP编程10小时,很多时候都在处理这类问题。

这个问题PHP短期内无法处理,因为它是属于全角字符的编码的原因。以前写过7年的ASP程序,ASP、JavaScript就不存在这个问题,它们都是把全角字符认为是一个字符。而PHP在GBK/GB2312下,把全角字符拆分成2个字符,UTF-8编码下,拆分成3个字符。

如果要专项替换这个全角空格,还有一个办法,不使用str_replace,稍微有点复杂,但是这个方法(公式)在项目中会特别常用。

以GB2312编码为例,让循环程序检索整个字符串,进行累加。例如:

$a1是字符串:

$a1='这是心灵博客的一个测试用 例';

$j=strlen($a1)-1;$c1='';

for ($i=0;$i<=$j;$i++){$a=$a1[$i];if (ord($a)>126){$a=$a.$a1[$i+1];$i++;}

if ($a==' ') $a='';

$c1.=$a;

}

echo $c1;?>

运行结果:这是心灵博客的一个测试用例

完美替换掉了全角空格。

当出现全角字符时,ord的值会大于126时,说明此字符一定是全角汉字,此时$i++会向下跳过一个半角字符。

同理,如果是UTF-8编码,则改为:

if (ord($a)>126){$a=$a.$a1[$i+1].$a1[$i+2];$i+=2;}

更新于:2019-11-22 23:05:04 栏目:网站周边/代码 关键词:php,php代码,str_replace

本站使用「署名 4.0 国际」创作共享协议,可转载、引用,但需署名作者且注明文章出处

推荐文章

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 当使用phpstrtoupper函数将文转换为大写字母时,可能会出现乱码的情况。这是因为phpstrtoupper函数只适用于ASCII字符集,对于Unicode字符集的文字符集,需要使用mb_strtoupper函数来转换。 因此,要解决这个问题,可以使用mb_strtoupper函数来将文转换为大写字母,如下所示: ``` $str = '你好,world!'; $str = mb_strtoupper($str, 'UTF-8'); echo $str; ``` 这样就可以将文转换为大写字母,同时避免出现乱码问题。 ### 回答2: 当phpstrtoupper函数在转换文时出现乱码问题,可以采取以下解决方案: 1. 设置字符编码:首先,确保你的php文件使用的字符编码与包含文的字符串的编码一致。可以在php文件的开头添加以下代码,指定编码为UTF-8: ```php header('Content-Type:text/html;charset=utf-8'); ``` 2. 使用mb_strtoupper函数:strtoupper函数只能处理ASCII字符,不能处理多字节字符,因此在处理文时会出现乱码。可以使用mb_strtoupper函数代替,该函数可以处理多字节字符。使用方法如下: ```php $chineseStr = "你好"; $upperStr = mb_strtoupper($chineseStr, 'UTF-8'); echo $upperStr; ``` 3. 转换为整体大写:如果只是需要将文字符串转为大写,可以使用mb_convert_case函数,并设置转换选项为MB_CASE_UPPER: ```php $chineseStr = "你好"; $upperStr = mb_convert_case($chineseStr, MB_CASE_UPPER, 'UTF-8'); echo $upperStr; ``` ### 回答3: 在使用phpstrtoupper函数转换文时,往往会出现乱码的现象。这是由于strtoupper函数默认使用ISO-8859-1字符编码,而文字符无法用该编码进行正确的转换,从而导致乱码的出现。 要解决这个问题,有以下几种方法: 1. 使用mb_strtoupper函数:该函数是mbstring扩展提供的用于处理多字节字符的函数,可以正确处理文字符的大小写转换,避免乱码问题。只需将原本的strtoupper函数替换为mb_strtoupper函数即可。 例如:$result = mb_strtoupper($str, 'UTF-8'); 2. 扩展strtoupper函数:我们可以自定义一个函数,用于将文字符转换为大写字母,而不影响其他非文字符的转换。可以使用正则表达式匹配文字符,然后将其替换为对应的大写字母。 例如: function myStrtoupper($str) { $pattern = '/([\x{4e00}-\x{9fa5}])/u'; return preg_replace_callback($pattern, function($matches) { return strtoupper($matches[1]); }, $str); } $result = myStrtoupper($str); 3. 重新设置字符编码:如果实际情况允许,我们可以尝试将整个程序的字符编码统一设置为UTF-8或其他能够正确处理文字符的编码,从而避免乱码问题。 无论采用哪种方法,我们都应该根据实际情况选择最适合的解决方案。如果只需要转换少量文字符,使用mb_strtoupper函数可能是最简单和方便的;如果需要在多个地方进行文转换,可以考虑自定义函数或重新设置字符编码来解决乱码问题

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值