有关php页面中的BOM解决方案

     这几天在调式一个ECshop的项目中遇到PHP的BOM问题,问题如下:在IE中打开网站,页面可以正常显示,但当点击其他页面后再回到首页则首页不能正常加载,需要刷新一次后才能正常加载。在谷歌和360浏览器下能正常加载,但页面顶部出现20px的空行,而在Firefox浏览器中都正常。几经查证,最后才发现原来是二次开发中编码出现了问题。PHP文件用记事本编辑保存后产生了BOM。

    BOM的说明:在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FEFF在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来标记文本文件的编码方式的。

    UTF-8编码的文件中,BOM占三个字节。如果用记事本把一个文本文件另存为UTF-8编码方式的话,用UE打开这个文件,切换到十六进制编辑状态就可以看到开头的FFFE了。



    很多软件都是通过BOM来识别这个文件是否是UTF-8编码的,可是,还是有很多软件不能识别BOM。如:在Firefox早期的版本里,扩展是不能有BOM的,不过Firefox 1.5以后的版本已经开始支持BOM了,PHP在设计时就没有考虑BOM的问题,也就是说他不会忽略UTF-8编码的文件开头BOM的那三个字符。 

    写好的程序上传到服务器中在本机没问题,结果到了服务器上到处是空行,于是我们需要散掉这些Bom。当然手工删是不现实的,别告诉我您做的页面就几个。所以放出一段代码专门用于删BOM。

    可以把代码保存成一个php文件,放在网站根目录下,需要时执行一下即可。

<?php

    if (isset($_GET['dir'])){ //可以传参数指定删哪些目录
         $basedir=$_GET['dir'];
    }else{
       $basedir = '.';
    } 
   $auto = 1; 
checkdir($basedir);
   function checkdir($basedir){  //检查目录

      if ($dh = opendir($basedir)) {

           while (($file = readdir($dh)) !== false) {

               if ($file != '.' && $file != '..'){

                   if (!is_dir($basedir."/".$file)) {
                      echo "filename: $basedir/$file ".checkBOM("$basedir/$file")." <br>";

                   }else{

                       $dirname = $basedir."/".$file;

                     checkdir($dirname);

                  }

             }

         }

        closedir($dh);

      }

   }

  function checkBOM ($filename) { //检查当前文件中是否存在Bom标记

        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并清除了</font>");

         } else {

            return ("<font color=red>没有Bom,不做任何处理</font>");

            }

       } 

       else return ("BOM Not Found.");

   }

  function rewrite ($filename, $data) {//覆盖原文件

       $filenum = fopen($filename, "w");

      flock($filenum, LOCK_EX);

     fwrite($filenum, $data);

     fclose($filenum);

  }

  ?>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值