参考:link标签和script标签跑到body下面,网页顶部有空白,出现“锘匡豢”乱码,UTF-8 BOM,EF BB BF
总是有七弯八拐的原因让我们要将自己的PHP源码从GB2312转换到UTF8,而90%的情况下你会遇到麻烦——很有可能你已经不是第一个想将你手头的系统转换到UTF8的人,只不过前面那些人都被整郁闷了,因而你也有了这个机会。
1、编码转到UTF-8可能出现的问题
转换起来并不麻烦,而且网上有很多工具可以用于转换,但不推荐使用工具进行批量转换,编码转换时的不确定因素太多,比如原编码,甚至系统语言等,都会引起转换的失败。
PHP源码直接转换到UTF-8后,很有可能会遇到下面的两个问题:
- 1、首行代码为空;
- 2、顶行有多个“锘匡豢”;
当然,很多人已经解决了,还发了博文——不过这文章是让你郁闷的。这位用了两天时间终于解决了问题,但却舍不得与人分享一下。当然也有很靠谱的人,提供了使用VS进行解决的方法,不过搞PHP开发的还装VS的可能不多。
导致出现以上问题的原因,可以看一下维基BOM词条,解决的方法也很简单,转换成UTF8后,将BOM的问题解决即可。很多人使用UltraEdit32,这也是个方法。不过还有更方便的选择,使用Notepad++会更简单,更安全。
2、使用Notepad++进行转换的方法
使用Notepad++,打开所有需要转换的文件,然后战壕菜单“Encoding(编码)”→“Convert to UTF-8 without BOM(转换为UTF-8无BOM编码格式)”,再保存文件,即可完成无恙转换。
顺便提一下,Notepad++的确是一个非常优秀的编辑器,完全可以作为你Win下的主力代码工具——它已经是win下我唯一用的代码工具了。
3、转换中需要注意的问题
转换很简单,但还需要注意以下几个方面的问题:
- 1、HTML中HEAD部分中对编码的指定,一般可能设置了charset,将值改成UTF8即可;
- 2、apache等web服务器中的默认编码设置,CentOS中的apache在httpd.con里修改,搜索“AddDefaultCharset”,将后面的值改为UTF-8;
- 3、CSS文件编码的修改;
淘宝也是用的gbk,转换起来一定又是一个折腾人的过程。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
link标签和script标签跑到body下面,网页顶部有空白,出现“锘匡豢”乱码,UTF-8 BOM,EF BB BF
最近在做一个简单的记账系统,用php+mysql。在要完工的时候发现了一个问题,研究了2天的时间才有了答案。
以下是页首的裁图:
页面的头部有空白区域。有的人可能怀疑是css的margin,padding,border没有重置为0造成的。其实不然,我已经将这几个属性重置为0。
而且在firebug下面查看HTML代码会发现link标签和script表情跑到body下面:
并且body标签下面和link标签之间有空行。
我自诩的查看我的模板文件是没有任何问题的,想了很久最后实在是没辙了,跑到Stackoverflow高手云集的地方去提问。
有个人提出了是页面中存在stray text。
You've got some stray text content inside the , before the tag. The browser sees the text and decides this means you're starting the main document body but have forgotten to include the tag.
This is actually valid—if inadvisable—in HTML4: the end-tag and start-tag are both optional. This is how you can have just Hello! as a valid HTML document. But it's not permissible in XHTML, so if you validate your document you should get a “character data is not allowed here” error at the point the stray text occurs.
The browser then parses the rest of the document as body content, putting the inside the body (which is not valid, but which is nonetheless commonplace). It ignores the real when that comes along because it already has a body.
If you can't see the stray text, perhaps it's an invisible character like U+00A0 No-break space or—most likely for Chinese documents—U+3000 Ideographic space , which you may get when you press space in some input method modes. These characters won't be visible, but they're not ‘ignorable whitespace’ like a normal U+0020 Space or newline, so they trigger ‘text content’ processing and force the .
就是说页面存在浏览器不能忽略的空白,比如U+0020活U+3000之类的。
我的php脚本全部使用的是utf-8编码,html页面的charset也就是utf-8,我强制让浏览器把页面用其他编码来解析,比如GB2312,然后出现了如下图的情况:
空白的部分出现了乱码,而且内容都是“锘匡豢”,这下子更是把我搞糊涂了。我按照SO上面bobince兄的建议,把模板页传到W3C markup validator上面去检查,得出来如下结论:
大概意思是说,UTF-8中的BOM编码在一些编辑器或者是浏览器中支持不好,可能会出现问题。
然后网上搜索了关于Byte Order Mark的信息:
在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输 字符"ZERO WIDTH NO-BREAK SPACE"。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little- Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
Windows就是使用BOM来标记文本文件的编码方式的。
然后我用UltraEdit的16进制编辑模式查看代码,都是EF BB BF开头的,说明都是带BOM的。我手动的将所有文件转成UTF-8 without BOM。页面终于正常了。link,script标签乖乖的跑到head下面,网页顶部空白消失。oh yeah。这就是搞了2天的答案。
最后我在网上随便下载了知名php程序的utf-8版,发现都是UTF-8 without BOM的。
那么我们继续回头看看出现问题的现象就有答案了。“锘匡豢”在页面头部出现多次的原因是首页处理文件index.php require_once了多个类和库文件,而那些库和类文件都是用的带BOM的UTF-8,所有PHP无法识别,直接将EF BB BF输出,在charset="utf-8"的页面中是空白,在GB2312的页面中的输出的就是一个稀有汉字。不信可以查锘匡豢这几个字的GB2312 代码是多少:
UTF-8编码是变长的,1—6个字节。其中汉字编码,是3个或4个字节。而恰好EF BB BF多次出现,两个EF BB BF组成EFBB BFEF BBBF ,而EFBB BFEF BBBF就是“锘匡豢”的UTF-8编码。这也是很多网站页面顶部出现“锘”加一个方框。
看来得找个时间恶补编码知识了。