天空之城

您当前位置>>首页>>PHP学习>>PHP其它>>PHP文件头BOM带来的困惑(frameset无法显示,头部一行空白)

PHP文件头BOM带来的困惑(frameset无法显示,头部一行空白)

来源:新浪博客   时间:2014-03-30 20:37:37   编辑:administrator   阅读数:256

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

PHP文件头BOM带来的困惑(frameset无法显示,头部一行空白)

  前些日子本地文件上传到服务器上,某些文件头部总是出现一条空白,无论怎么修改文件都无法去除空白,用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);  

}   

?>

 

2014/04/03补

网页打不开用火狐出现“内容编码错误”,查看下文本文件编码格式,发现有BOM头,原因是用记事本修改php文件,以上也有讲到

PHP文件头BOM带来的困惑(frameset无法显示,头部一行空白)
原文地址: http://blog.sina.com.cn/s/blog_6dbbafe00101bcmi.html

上一篇:PHP设计模式之:原型模式
下一篇:PHP连接MySQL报错:Fatal error: Call to undefined function mysql_connect()之解决方法

    just do it
    天空之城天空之城