解决require_once后顶部输出空白行问题

转自http://window1972.blog.163.com/blog/static/92024602011322112333960/

在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标记,各种浏览器的处理方式不同,Firefox会忽略,而IE则会产生输出或者忽略一次。而输出的效果则是一个空行或者乱码。这刚好就解释了为什么我之前编辑好的文件(含有一个BOM标记)显示正常,当我使用require_once包含进另一个文件时,就产生了两个BOM标记,而浏览器只忽略第一个,第二个BOM标记则被作为空行被输出了。所以出现了明明正常的CSS样式,顶部却多了一个空白行。

Windows就是使用BOM来标记文本文件的编码方式的,所以如果用记事本编写代码,然后另存为UTF-8格式,文件头就会自动加入这个BOM标记。UTF-8编码的文件中,BOM占三个字节,标记值为EF BB BF。

既然知道BOM的标记值为EF BB BF,那就可以写段代码批处理了


<?php
//shadowchao.com
$s=0;//统计成功数
$f=0;//统计失败数
//遍历所有文件
function find_allfile(){
  $i="*";
  while($file=glob($i)){
      foreach($file as $s){
        if(!is_dir($s))$allfile[]=$s;
    }
    $i.="/*";
  }
  return $allfile;
}
//清除BOM标记
function del_bom(){
  global $s,$f;
  $file=find_allfile();
  foreach($file as $fname){
    $fname=dirname(__FILE__)."//".$fname;
    $filecont=@file_get_contents($fname);
    $bom=substr($filecont,0,3);
    $bom=bin2hex($bom);
    if($bom=="efbbbf"){ //判断文件中的前3个字节是否为BOM标记值
      $filecont=substr($filecont,3);
      $result=@file_put_contents($fname,$filecont,LOCK_EX);
      if($result){
        echo "[file] $fname --- --- <em style=/"color:green/">清除成功</em><br />";$s++;
      }else{
        echo "[file] $fname --- --- <em style=/"color:red/">清除失败</em>(文件只读或者被占用)<br />";$f++;
      }
    }
  }
}
del_bom();
if($s==0 && $f==0){
  echo "<p>所有文件正常,没有发现BOM标记。</p>";
}else{
  echo "<p>统计结果:清除成功($s) | 清除失败($f)</p>";
}
?>


写入 del_bom.php文件中

放入网站路径中,IE中执行 http://localhost/del_bom.php

或 cmd 提示符下 php del_bom.php

posted on 2012-11-10 11:10  zhanghongji  阅读(429)  评论(0编辑  收藏  举报