Loading...

棘手的UFT-8编码问题

2008-07-13 22:35:19 发表于网站技术 本文链接: 棘手的UFT-8编码问题

解决了一个utf8编码的问题,自己高兴一下。

从某个时候开始(应该是给servlet折磨之后),本人的php程序编码就只有utf-8的编码格式了,所以从不去考虑gb2312以及GBK,但是最近写一个程序的时候却遇到了很大的麻烦。该程序是一个数据导入程序,导入到文件格式很多,需要php自动分析,这个似乎难不倒我,但是问题在于这些文件的编码方式不一样,有的是gb2312,有的是utf-8,麻烦可大了。当然,或许有朋友要吧iconv或者mb_convert_encoding函数介绍给我,这些函数都一一尝试过,它们有一个严重的问题就是转换之后丢失文字。

最初的时候我以为导入文件都是GB2312的编码,所以我做了两次处理。首先将上传文件的表单提交给一个GB2312编码的php(do-gb2312.php)程序,这样从文件中读取的内容可以正常显示,然后通过ajax将php读出的结果返回到utf-8编码的一个表单中,再次用javascript提交该表单,问题解决了。然而问题并没有解决,因为用户还有另外的导入格式,而这些格式中居然又出现了UTF8的编码模式,刚才的程序好不容易把GB2312编码的文件处理好,但是UTF-8编码又出问题了。

想了很久,最后终于出绝招了。将do-gb2312.php原封不动的以utf-8编码的格式保存成另外一个文件do-utf8.php,在do-gb2312.php中加上编码判断。主界面的表单默认还是提交给do-gb2312.php,当do-gb2312.php中发现文本编码是UTF8格式的时候,通过js自动将主界面的表单提交域改成do-utf8.php,再次提交,大功告成,终于圆满的解决了此问题,毕竟中文除了GB2312和UTF8编码模式之外基本不会有其他的编码模式了。

下面是相关的函数,和一篇墙外相关的文章(虽然他没有解决我的问题,但是还是很有用的,所以我将它搬回到墙内)function isUTF8($str){
if ($str === mb_convert_encoding(mb_convert_encoding($str, "UTF-32", "UTF-8"), "UTF-8", "UTF-32")){
return true;
}else{
return false;
}
}

php 5的流读取函数好像默认编码是UTF-8,以前在php 4里直接file_get_contents()读取gb2312编码的正常,到了5就乱码了。网上的解决办法说抓取后用iconv()转码。看后我就觉得不对劲:一个是不一定编译了iconv库,更大的问题是编码都跟流转换的时候有关(如果用了iconv实际上php转了两次码:流 -> UTF-8 -> GB2312):这不是白忙乎了吗?

仔细看了下php的文档(不知道大家都是怎么写代码的,其实文档上很清楚啊),上面关于fopen()及file_get_contents()都提到了“默认是UTF-8,但是用户可以用stream_default_encoding()或者用户自定义上下文属性改变编码”(If unicode semantics are enabled, the default encoding of the read data is UTF-8. You can specify a different encoding by creating a custom context or by changing the default using stream_default_encoding().)。于是用stream_default_encoding(’gb2312′);测试:但是 faint的是,这个函数不存在?!似乎php 6才支持。不过天无绝人之路,还有“用户自定义上下文属性”可以用。

经过更仔细的看文档,最后解决了这个问题:

//设置流的编码格式,这是文件流(file),如果是网络访问,file改成http
$opts = array('file' => array('encoding' => 'gb2312'));
$ctxt = stream_context_create($opts);
file_get_contents(文件名, FILE_TEXT, $ctxt);
from:http://bianbian.org

还是贴一个原理图吧,

标签:
发表于 2008-07-13 22:35:19 目录:网站技术 [RSS 2.0] 你可以发表评论, 或者从您的网站 trackback
  • 相关阅读
  • homezz 美国专业主机商
    已经有4位大师动手指导 拒绝低俗
    评论分页: 1
    (Required)
    (Required, not published)
    如果留言未显示无需重复留言,我将为你恢复!