在我以前有两篇文章介绍了汉字的编码问题:汉字编码问题和汉字编码相关原理 而我在用php时也常发现在不同的应用程序下出现不同现象的问题。所以在这里加以测试,环境仍为windows xp sp2下:
用记事本建立文件test.php,这次的文本内容比上次测试用的"联通zZ"复杂,用的是一个完整PHP文件test.php 代码如下:
<? echo "易易eE"; ?>
该文件一方面是完整的PHP,另一方面又有中文,英文和回车,便于比较。
用windows 记事本建立该文件后,用ultraEdit打开。用Ctrl+H查看16进制编码为:
3C 3F 20 65 63 68 6F 20 22 D2 D7 D2 D7 65 45 22 3B 0D 0A 3F 3E
对应的关系为:
<:3C ?:3F 空:20 e:65 c:63 h:68 o:6F 空:20 ":22 易:D2 D7 易:D2 D7 e:65 E:45 ":22 ;:3B 换行:0D 回车:0A ?:3F >:3E
这时,如果选择“文件”->转换->“Dos转Unix”则16进制仍为:
3C 3F 20 65 63 68 6F 20 22 D2 D7 D2 D7 65 45 22 3B 0D 0A 3F 3E
看上去跟原来的一模一样。这是为什么呢,因为ultraEdit在打开unix格式的文本文件时会询问是“否转为Dos格式”。这种情况就相当于将文件转换为Dos格式,但在ultraEdit的状态栏上会发现unix字样。也就是说该文件在保存的时候会自动转为unix格式。现在将该文件用ultraedit保存,并关闭ultraEdit,再打开该文件,则会出现提示:“你想转换test.php”为Dos格式吗?若回答是,则Hex编码同dos一样,若回答否,则Hex编码为:
3C 3F 20 65 63 68 6F 20 22 D2 D7 D2 D7 65 45 22 3B 0A 3F 3E
显然,少了OD即C语言里的\r 回车。这也是unix文本文件同Dos文本文件的区别。
现在将该文件用zend打开(注:首选项是gb2312才能打开gb2312的php文件,否则乱码)。这时如果test.php是unix格式的,则zend按unix格式编辑,如果是dos格式的,则按dos格式编辑。
为了便于讨论,以下将只讨论dos格式,因unix格式的唯一区别就是换行是少一字节(0D):
现在将test.php在zend里另存为编码为'default'或'gb2312'则无改变,如果另存为'utf-8'用ultraEdit打开,看到的是一乱码了。如果在运行该php,显示的是正常的utf-8,可用ie阅读。16进制码为(未转为Dos):
3C 3F 20 65 63 68 6F 20 22 E6 98 93 E6 98 93 65 45 22 3B 0A 3F 3E
对应的关系应该为:3C 3F 20 65 63 68 6f 20 22 同前者一样。65 45 22 3b 0a 3f 3e也同前者一样。关键不同的就是两个汉字。汉字编码现在为e6 98 93 ,如果同样用记事本打开该文件,看到的却是正常的非乱码文件。为什么呢,说明ultraedit读取文件时判断为简单的dos格式而不是uf-8格式。
在ultraEdit里有一种方法可以将乱码转换为非乱码,那就是:文件->转换->unicode/utf-8 转 utf-8(unicode)编辑。这时看上去就不是乱码了。对应的hex为:
FF FE 3C 00 3F 00 20 00 65 00 63 00 68 00 6F 00 20 00 22 00 13 66 13 66 65 00 45 00 22 00 3B 00 0A 00 3F 00 3E 00
在文件的头部多了FF FE ,非汉字后面多了00,而汉字的编码也不一样了!(同样用utf-8转acsii utf-8转unicde 转出来的结果是一模一样的)
但是有个问题。使用该方式编辑后再保存文件却只有22字节,而在hex下观察却有38字节,说明在保存的时候ultaedit已经将内容进行了转换保存成相应的格式。这样我们就无法用ultaedit看到真实保存的16进制,现在用另一工具010editor把文件打开。
现将该转换后的用ctlr+s保存再打开还是乱码,这时用zend打开也是乱码!用010editor查看十六进制为
3C 3F 20 65 63 68 6F 20 22 E6 98 93 E6 98 93 65 45 22 3B 0A 3F 3E 这跟zend保存时是一样的,为什么打开却是乱码呢?原来zend保存时以utf-8保存,在打开时却不是以utf-8打开,只要更心工具->首选项->桌面,将编码改为utf-8,再用zend打开则正常了。
这里说明没有前导字符的情况下用ultaeidt编辑文件,保存时还是没有前导字符。也就是直接打开时还是乱码。
现在用记事本来打开test1.php 显示正常,再直接另存为test2.php,这时再用ultraedit打开,现在
EF BB BF 3C 3F 20 65 63 68 6F 20 22 E6 98 93 E6 98 93 65 45 22 3B 0A 3F 3E
EF BB BF 表明是utf-8的前导字符。后面表示同zend里出来是一样的。但现在用zend打开该文件,会出现同ultraedit打开同样的错误,把前导字符也当成字符了!这时把zend的首选项改为:utf-8再去打开test1.php 和test2.php两者都能正常显示,但后者<前都了一个不可识别字符。若删去后保存则这两个文件就一模一样的。也就是记事本在保存test1.php 到test2.php 时加上了前导字符:EF BB BF
怎样才能让ultraedit编辑器能够自动认识utf-8格式文件呢。其实,工具->配置->里有一个选项“自动检测utf-8文件就能识别以上的test1.php和test2.php了。
另外对于dreamweaver 在编辑utf-8时可以选择是否使用BOM选项的。