• 检查PHP文件头BOM


      前些日子本地文件上传到服务器上,某些文件头部总是出现一条空白,无论怎么修改文件都无法去除空白,用firebug查看header部分同样有一片空白,删除后空白消失,但是在文件里却无法找到那个空白的部分,纠结了好久也没解决;昨天则是后台登陆后显示空白,用的是frameset,单独使用某个部分内容是可以显示的,但是在后台首页index.php下用frameset却无法显示,今天上网查了下,刚好有一个帖子也是说frameset无法显示的问题,有谈到是PHP头文件BOM的影响,之前也了解过PHP头部BOM,知道自己应该是找到问题的答案了(之前的头部空白也是),便查了一下相关BOM的资料.

    BOM

    BOM: Byte Order Mark
    UTF-8 BOM又叫UTF-8 签名,其实UTF-8 的BOM对UFT-8没有作用,是为了支援UTF-16,UTF-32才加上的BOM,BOM签名的意思就是告诉编辑器当前文件采用何种编码,方便编辑器识别,但是BOM虽然在编辑器中不显示,但是会产生输出,就像多了一个空行,

     

    如果您在修改任何PHP文件後发生:

    * 页顶出现一条空白; * frameset无法正常显示(单独使用可以); * 不能登入或者不能登出; * 页顶出现错误警告; * 其它不正常的情况.

     

    这些大部分是编辑器的问题,PHP文件采用UTF-8编码,PHP开发大部分使用的文本编辑软件如:Zend studio、editplus、eclipse等等都可以显示并编辑UTF-8编码的文件,但是也有一些软件不能满足这个要求.

    类似如windows的记事本,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM).它是一串隐藏的字符,用于让记事本等编辑器识别这个文件是否以UTF-8编码.对于一般的文件,这样并不会产生什么麻烦.但对于 PHP来说,BOM是个大麻烦.

    对于BOM,PHP并不会忽略,在读取、包含或者引用这些文件时,PHP会把BOM作为文件开头正文的一部分,根据嵌入式语言的特点,这串字符将被直接执行(显示)出来.这就导致了一些页面的头部总是有一条白条,尽管样式padding、margin等各方面都设置好也无法让整个网页紧贴浏览器顶部,这头部白条就是这3个不可见的字符(0xEF 0xBB 0xBF,即BOM);

    另外还有的问题就是,受COOKIE送出机制的限制,在这些文件开头已经有BOM的文件中,COOKIE无法送出(因为在COOKIE送出前PHP已经送出了文件头),所以登入和登出功能失效.一切依赖COOKIE、SESSION实现的功能全部无效.

    所以,在编辑、修改任何文本文件的时候,请使用不会乱加BOM的编辑器.Linux下的编辑器应该都没有这个问题.WINDOWS下,请勿使用记事本等编辑器.推荐使用Editplus,Zend studio、eclipse等编辑器.

    其他的对于已经添加了BOM的文件,要取消的话,可以用不会乱加BOM的编辑器另存一次.当然也可以使用以下方法去除该目录下所有文件的头部BOM:

     

    把以下代码复制到一个PHP文件里面,运行该PHP文件,就可以批量清除该文件相同目录下所有文件的头部BOM.

    <?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) {  
    
        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);  
    
    }  
    
    ?>
    
    指定目录或文件清除BOM:
    
    <?php
    
    if(isset($_GET['dir']) && !empty($_GET['dir'])){ //设置文件目录  
    
        $basedir=$_GET['dir'];  
    
    }else{  
    
        $basedir = '.';  
    
    }  
    
    if(empty($_GET['filename'])){                        //设置文件    
    
        $auto = 1;  
    
        checkdir($basedir);  
    
    }else{
    
        $file = $_GET['filename'];
    
        echo "filename: $basedir/$file ".checkBOM("$basedir/$file")." <br>";
    
    }
    
    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) {  
    
           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);  
    
    }   
    
    ?>

     

  • 相关阅读:
    js文件内部导入引用js文件方法
    CSS3.0动画之hover---Y轴----3D旋转
    静态的html页面想要设置使用浏览器缓存
    opener 属性是一个可读可写的属性,可返回对创建该窗口的 Window 对象的引用
    input获取永久焦点
    修改zepto源代码,使支持wp8的ie10
    EChart
    input属性disabled和readonly的区别
    trigger
    解决jquery mobile的遇到高版本Chrome一直转圈,页面加载不出来的情况。
  • 原文地址:https://www.cnblogs.com/sunscheung/p/4493187.html
Copyright © 2020-2023  润新知