在编写或者修改用UTF-8编码保存的PHP文件时,有时会莫名其妙出现一些问题:

1. 页面显示一个“锘”字,其他一片空白;
2. 不能登入或者不能登出;
3. 页顶出现一条空白;
4. 页顶出现错误警告;
5. 其它不正常的情况;
6. 生成的图片浏览器无法识别。

分析原因:
 文件以UTF-8编码保存时,有两种情情况:带Unicode签名(BOM)和不带Unicode签名。BOM信息是文件开头的一串隐藏的字符,用于让某些编辑器识别这是个UTF-8编码的文件。

类似WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM——Byte Order Mark)。它是一串隐藏的字符,用于让记事本等编辑器识别这个文件是否以UTF-8编码。对于一般的文件,这样并不会产生什么麻烦。
   
    但对于 PHP来说,PHP在设计时就没有考虑BOM的问题,不会忽略UTF-8编码的文件开头BOM的那三个字符,会把BOM作为该文件开头正文的一部分。由于必须在<?或者<?php后面的代码才会作为PHP代码执行,所以将会造成在页面上输出这三个字符,显示效果就要看浏览器了,一般是一个空行或是一个乱码。由于在html一开头有这3个字符的存在,即使页面的 top padding 设置为0,也无法让整个网页紧贴浏览器顶部。由于受COOKIE送出机制的限制,在这些文件开头已经有BOM的文件中,COOKIE无法送出(因为在 COOKIE送出前PHP已经送出了文件头),所以登入和登出功能失效。一切依赖COOKIE、SESSION实现的功能全部无效。

解决办法:

在编辑、更改任何文本文件时,请务必使用不会乱加BOM的编辑器。Linux下的编辑器应该都没有这个问题。WINDOWS下,请勿使用记事本等编辑器。推荐的编辑器是:Editplus 2.12版本以上;EmEditor;UltraEdit(需要取消‘添加BOM’的相关选项);Dreamweaver(需要取消‘添加BOM’的相关选项)等。

对于已经添加了BOM的文件,要取消的话,可以用以上编辑器另存一次。(Editplus需要先另存为gb,再另存为UTF-8。)

ultraedit, editplus, notepad四个工具对UTF-8 的支持不相同,下面是对四个工具对UTF-8 支持的总结:
  UTF-8 BOM header: 是三个字符: EF BB BF。
  1. notepad
        notepad 在保存时,选择UTF-8 格式,会在文件头写上BOM header.
  2. editplus
        文件保存时,选择UTF-8 格式,不会在文件头写上 BOM header.
  3. ultraedit
        ultraedit 对UTF-8 的支持最为完备。在advanced->configuration中可以    选择文件保存时是否写上BOM header.
  4. vi
        指的是Linux 下的vim, 如果UTF-8 文件开头有BOM header, 其能够正常显示UTF-8编码,否则,显示为乱码。
  还有一些编码转换工具,比如,可以用java 写一个简单的编码转换工具,这些工具是不会增加BOM header的。

附录:

UltreEdit的配置,将选项“保存时对所有UTF-8写入UTF-8文件头标记(BOM)”关闭。即:Write UTF-8 BOM header to ALL UTF-8 files when saved OFF。
    不同版本有可能没有,而要把“自动检测utf8”关掉。这样看utf8文件就乱码了。
    建议用editplus了。

检测目录下文件是否有BOM程序:
<?
//此文件用于快速测试UTF8编码的文件是不是加了BOM,并可自动移除
//By Bob Shen

$basedir=".";; //修改此行为需要检测的目录,点表示当前目录
$auto=0; //是否自动移除发现的BOM信息。1为是,0为否。

//以下不用改动

if ($dh = opendir($basedir)) {
    while (($file = readdir($dh)) !== false) {
        if ($file!='.' && $file!='..' && !is_dir($basedir."/".$file)) echo "filename: $file ".checkBOM("$basedir/$file")." <br>";
    }
    closedir($dh);
}

function checkBOM ($filename) {
    global $auto;
    $contents=file_get_contents($filename);
    $charset[1]=substr($contents, 0, 1);
    $charset[2]=substr($contents, 1, 1);
    $charset[3]=substr($contents, 2, 1);
    if (ord($charset[1])==239 && ord($charset[2])==187 && ord($charset[3])==191) {
        if ($auto==1) {
        $rest=substr($contents, 3);
        rewrite ($filename, $rest);
        return ("<font color=red>BOM found, automatically removed.</font>");
        } else {
        return ("<font color=red>BOM found.</font>");
        }
    }
        else return ("BOM Not Found.");
    }

function rewrite ($filename, $data) {
    $filenum=fopen($filename,"w");
    flock($filenum,LOCK_EX);
    fwrite($filenum,$data);
    fclose($filenum);
}
?>

参考文章:
http://paingaingavin.spaces.live.com/blog/cns!7A6BACD7A08F1B4F!1767.entry
http://www.diggsoft.com/websoft/blog/200810-12-15045.html

PHP与Unicode签名(BOM)相关推荐

  1. php 签名 bom,PHP与Unicode签名(BOM,Byte Order Mark)

    在编写或者修改用UTF-8编码保存的PHP文件时,有时会莫名其妙出现一些问题: 1. 页面显示一个"锘"字,其他一片空白: 2. 不能登入或者不能登出: 3. 页顶出现一条空白: ...

  2. php 签名 bom,PHP教程:Unicode 签名(BOM)问题_php

    被 WordPress 模板的怪异代码空行折腾半天. 因为 Dansion 师兄的驱使,开始 Dreamweaver 征途.不过很少有人关注到,在 Dreamweaver 中使用 utf-8 编码保存 ...

  3. QT乱码总结3.UNICODE有无BOM

    QT乱码总结0.Qt乱码产生因素 https://blog.csdn.net/liujiayu2/article/details/103167953 QT乱码总结1.Unicode 和 UTF-8 h ...

  4. 用PHP去掉文件头的Unicode签名(BOM)

    <?php //此文件用于快速测试UTF8编码的文件是不是加了BOM,并可自动移除 //By Bob Shen $basedir="."; //修改此行为需要检测的目录,点表 ...

  5. CSV乱码 - UTF-8 Unicode (with BOM)

    Unicode 统一码,也叫万国码.单一码(Unicode)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字 ...

  6. Cannot send session cache limiter - headers already sent错误解决方法

    在windows下编程,当使用session_start()方法的时候,有时会报 session_start() [function.session-start]: Cannot send sessi ...

  7. PHP调试的时候遇到Warning: session_start() [function.session-

    今天调试PHP的时候,PHP调试的时候遇到Warning: session_start() [function.session-start]: Cannot send session cache li ...

  8. UTF-8文本文件头部出现乱码“锘*”的问题及解决方法

    昨天发现一个ini配置文件,在某些机器上修改后程序无法识别的问题.DBinfo_old是修改后,DBinfo.ini是修改前. 同一份程序,可以正确识别DBinfo.ini中的DBAddress等内容 ...

  9. UltraEdit如何自动换行

    UltraEdit是一款功能强大的文本工具,可以用于编程.安装UltraEdit之后,默认的设置没有自动换行.设置的方法是,点击菜单栏的"高级→配置",找到"编辑器→自动 ...

最新文章

  1. 以太坊钱包1-Android-创建钱包
  2. VTK:可视化之TextureMapQuad
  3. presto读取oracle,Presto源码分析之数据类型
  4. jQuery的三种bind/One/Live事件绑定使用方法
  5. Apache Spark源码走读之3 -- Task运行期之函数调用关系分析
  6. python 化学模块_Python chemif包_程序模块 - PyPI - Python中文网
  7. linux ipconfig和route 命令
  8. USACO 2006 Open, Problem. The Country Fair 动态规划
  9. 冲刺一团队五亲亲精英队
  10. Unity 编辑器知识(—)如何绘制色块
  11. JetBrains 2017/2018全系列产品激活工具
  12. maven中引用JDK中的tools jar
  13. Java实现Excel导入和导出,看这一篇就够了(珍藏版)
  14. Python如何实现简单DNF脚本
  15. 【从零开始学架构-李运华】09|架构设计原则案例
  16. (六)【模电】(基本放大电路)静态工作点的稳定
  17. 算法设计-天下会评选一级弟子
  18. 格拉姆矩阵(Gram Matrix)
  19. RECON-NG介绍及使用
  20. 全球智慧能源解决方案服务商「雄韬股份」牵手企企通,谱写采购数字化变革之路

热门文章

  1. iOS 使用符号断点定位警告约束警告-[LayoutConstraints] Unable to simultaneously satisfy constrai...
  2. 第八届蓝桥杯java b组第十题
  3. Jenkins+Github(Robotframework代码)
  4. redhat 6.5 vnc 配置
  5. XCode6.0的iOS免证书真机测试方法(MAC及黑苹果均有效)
  6. 事件库之Redis自己的事件模型-ae
  7. Android颜色选择器库
  8. session原理总结
  9. 恢复Cisco路由器密码
  10. Linux 硬链接与软链接