如何用 PHP 搞定中文字符编码问题

2015-03-05 17:49:52 +08:00
 Jack

主要功能是从压缩包中读取文本文件的部分内容

现在用PHP自带的函数已经可以做到从rar及zip压缩包中直接读取文件信息,也可以直接用zip_entry_read或fread读文本的内容,现在的问题是utf-8的页面读gbk文件,读出来也无法做任何转换可能了吧,试了些转换函数,无解。

所以唯一的办法还是把文件拿出来,整个都转了以后,读内容,然后再把文件删除这种办法了么

求解!

8198 次点击
所在节点    PHP
31 条回复
b821025551b
2015-03-05 17:59:16 +08:00
mb_convert_encoding($file, 'utf-8', 'gbk');
Jack
2015-03-05 18:30:09 +08:00
@b821025551b 所以还是要转整个文件了?
lincanbin
2015-03-05 18:43:26 +08:00
@Jack PHP里的编码转换函数大多数是输入一个string,而不是handle。
lk09364
2015-03-05 18:45:48 +08:00
iyaozhen
2015-03-05 19:48:31 +08:00
读出的文件内容就是字符串吧。
然后用mb_convert_encoding或iconv转换、输出不就行了。哪儿有问题?
msg7086
2015-03-05 19:54:09 +08:00
不就是读gbk的字幕么?
拿到文字以后iconv一下就好啊
Jack
2015-03-05 20:58:29 +08:00
@lincanbin
@lk09364
@iyaozhen


mb_convert_encoding($content,'utf-8', array('Unicode','ASCII','GB2312','GBK','UTF-8'));
转换成功了大部分,但是还是有字符的编码PHP也检测不出来是啥编码,而且这文件在mac里还能正常看到。。。但是utf8页面浏览是乱码。。。mac不是UTF-8么
lk09364
2015-03-05 21:07:43 +08:00
@Jack 有例子吗?
kankana
2015-03-05 21:21:25 +08:00
编码问题真心麻烦啊.

php根本没法准确地判断出用户提供的源文件内容是啥编码字符集.

试了n种方法,还是没法完美解决. 仍然有些字符呈现 black diamond with question mark, 不过好歹保存时, mongo不报错了.

现在客户提到了这个 问号 问题, 我都不知道怎么解决... 你让他们文件保存时,编码选择utf-8, 能听懂吗??

lz要是解决了, 麻烦提供下方案. 我目前的方法.

$encoding = mb_detect_encoding($str, "auto");
mb_substitute_character("none");
mb_convert_encoding($str, 'UTF-8', $encoding);
kankana
2015-03-05 21:24:33 +08:00
我这里提供个文件供大家测试下.

http://expirebox.com/download/0b36bb0e05e52ceb66c8fc70a0eb12b0.html

看看有没有人能用php检测出这个zip的txt文件的编码字符集
kankana
2015-03-05 21:25:52 +08:00
或者直接转换成utf-8不报错
zado
2015-03-05 21:32:13 +08:00
先做一个高频字列表,然后把要转的字串各种可能的编码都转一遍,最后结果字串中高频字出现得多的就假定他是正确的.这是我想到的一个方法,没有实践过啊.
Jack
2015-03-05 21:50:26 +08:00
@kankana 你这么写还是有问题,我那段能搞定的你这段不行
Jack
2015-03-05 21:58:17 +08:00
@lk09364
http://expirebox.com/download/a6f9ca61560a889e2ebd4e47dbd5c356.html
试试这个,mac里面能打开,file_get_contents到页面中是乱码
kankana
2015-03-05 22:11:36 +08:00
@Jack 额.... 可能我们两的问题不太一样.

我那边的客户都是idiot, 上传的文件编码都是不同的, 但是我还是得把内容转换成utf-8...

所以, 你的方法也不行.

convert everything to utf-8
Jack
2015-03-05 22:38:51 +08:00
@kankana 我跟你的问题一样,我这边也是因为不知道上传文件的编码,每个人传的都不一样,才会来提问的。

我那个方法确实不是100%,但是能覆盖我这边90%的文件了,也搞定了你的代码搞不定的部分文件
typcn
2015-03-05 22:53:34 +08:00
kankana
2015-03-05 22:54:30 +08:00
@Jack


我用你的方法

mb_convert_encoding($content,'utf-8', array('Unicode','ASCII','GB2312','GBK','UTF-8'));

处理我之前给的链接的那个zip里面的txt, 还是失败了 mb_convert_encoding(): Unable to detect character encoding

我那个是txt是windows 1252编码, 你又没包含进去, 怎么能行呢? 哈哈,难道我人品问题
kankana
2015-03-05 23:19:17 +08:00
再试试你的birdman文件, 你我的方法, 都是卡在 mb_convert_encoding(): Illegal character encoding specified

看样子, 咱用的php版本可能不同, 我5.6

算了,不折腾了. 洗洗睡了. 明天国外问问, 其实也不抱太大希望... 遇到这类问题的很多..
lk09364
2015-03-05 23:31:45 +08:00
@Jack 这东西是UTF-16LE……OTL

http://php.net/manual/en/function.mb-detect-order.php
> For UTF-16, UTF-32, UCS2 and UCS4, encoding detection will fail always.

为什么呢… 我不知道……
我发现在我的环境里 mb_detect_encoding 不能正常分辨 UTF-8,UTF-16LE,BIG5 。

在网上东拼西拼拼出了这个东西,可以正常阅读你给出的文档。
https://gist.github.com/applelam/0497b2ce31d9784f32db

不过如果遇到UTF-16 without BOM 的话依然会出问题,
文字处理真的很麻烦呢……


@kankana 我连windows 1252 也未听说过——

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/174737

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX