字符编码转换的问题
公司从亚马逊上拉取日语数据下来,存到数据库,但是亚马逊可能给的是日语编码的,数据库格式是utf8的,存到数据库之后就乱码了:
Rampow iPhone儔僀僩僯儞僌働乕僽儖亂2M/Apple Mfi 擣徹/塱 媣曐徹亃 iPhone 11/11 Pro/11 Pro Max/XS/XS Max/XR/iPhone X/8/9 Plus/iPad/iPo
我尝试用以下代码解决,但是转出来的内容还是乱码:
$str = 'Rampow iPhone儔僀僩僯儞僌働乕僽儖亂2M/Apple Mfi 擣徹/塱 媣曐徹亃 iPhone 11/11 Pro/11 Pro Max/XS/XS Max/XR/iPhone X/8/9 Plus/iPad/iPo';
$fileType = mb_detect_encoding($str, ["JIS", "eucjp-win", "SJIS-win"]);
if( $fileType != 'UTF-8'){
$str = mb_convert_encoding($str ,'utf-8' , $fileType);
}
echo $str;
输出内容:
Rampow iPhone蜆泌ム蜒ゥ蜒ッ蜆槫レ蜒堺ケ募?蜆紋コ?M/Apple Mfi 謫」蠕ケ/蝪ア 蟐」譖仙セケ莠 iPhone 11/11 Pro/11 Pro Max/XS/XS Max/XR/iPhone X/8/9 Plus/iPad/iPo
我又尝试把源字符串,也就是Rampow iPhone儔僀僩僯儞僌働乕僽儖亂2M/Apple Mfi 擣徹/塱 媣曐徹亃 iPhone 11/11 Pro/11 Pro Max/XS/XS Max/XR/iPhone X/8/9 Plus/iPad/iPo
存在一个txt文本里,用Notepad++打开,结果一打开就显示了正常的日文:Rampow iPhoneライトニングケーブル【2MApple Mfi 認証永 久保証】 iPhone 1111 Pro11 Pro MaxXSXS MaxXRiPhone X89 PlusiPadiPo
,并且发现编码格式是Shift-JIS
请教一下大佬,这种格式应该怎么转成utf8,并显示正常的日文呢?
贴一下数据库内容,可以看到都是乱码的:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
来更新一下,最后算是解决了吧。源头已解决,剩下就是已经乱码的数据的转换。
因为看到notepad++可以让乱码可以还原成正常的日语,所以觉得还是有迹可循的。解决方式如下:
数据库中导出相关的数据,并且拼接成sql更新语句,例如:
然后把获取到的结果集,复制到txt文本里,另存为
ANSI
编码:然后把文件改成html后缀,浏览器打开,可以看到正常的日文数据:
然后复制浏览器里的sql语句,再次新建一个txt文件放进去,ctrl+s保存的时候,会提示需要保存到unicode编码,然后保存成unicode编码,这时候文件成了utf16格式,再次重复将utf16转换成utf8,就可以了。
然后这么大量的sql语句,可以形成一个文件,通过命令行执行
以上就是本次问题的解决方式,在找不到通过代码解决的时候,不妨一试。
$result为我从亚马逊MWS报告拉取的csv格式的字符串
实际上出现了检测出编码为ISO-8859-1,最后转码还是乱码。该$result写入xls文件,双击打开日文显示正常。
后面发现,我改变该检测字符编码函数的第三个参数,结果却各不相同:
$encode = mb_detect_encoding($result, array("UTF-8",'iso-8859-1',"Shift_JIS","cp1252",'UTF-16'));
$encode = mb_detect_encoding($result, array("UTF-8",'Shift_JIS',"iso-8859-1","cp1252",'UTF-16'));
$encode = mb_detect_encoding($result);
同一个字符串三个返回结果都不一样。分别为:
ISO-8859-1
SJIS
false
这个检测编码的函数可能存在问题,需要后续深入研究。
但是,第二和第三的结果分别会构成
$result = mb_convert_encoding($result, 'UTF-8', 'SJIS');
和
$result = mb_convert_encoding($result, 'UTF-8', 'Shift_JIS');
逻辑。
都会正常转换成日文。
我的猜想是:
mb_convert_encoding并不是一个严格函数,在第三个参数【待检测的字符编码列表】给出的情况下,他会按顺序检测字符特性的符合度,达不到,按给出列表的顺序逐个匹配,达到一定符合度就直接返回匹配的编码,后续不再检测。
所以,在一个字符串的字符特性与多个编码的匹配度满足符合度的情况下,谁排在前面就return谁。所以出现了第一和第二的不同编码返回。
所以我这里建议是,如果已知目标字符串是哪国编码,指定转换即可,或者在mb_detect_encoding的检测列表将该国编码或者可能性按大小依次排列
对于你这个问题,既然已知日文,直接
mb_convert_encoding($result, 'UTF-8', 'Shift_JIS');
试试。