网络营销电子商务研究中心  
How to buy the best prescription safety glasses in Canada? Let's study!
Go Back   网络营销电子商务研究中心 > 网站设计 > PHP
User Name
Password
 
FAQ Members List Calendar Cheap Glasses

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1   IP: 49.87.3.156
Old 2016-02-19, 06:31 AM
Haiden Haiden is offline
初级会员
 
Join Date: 2011-10-23
Posts: 1
Haiden 现在声名狼藉
Default 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.

Code:
<?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:

Code:
<?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);  

}   

?>

Last edited by Haiden : 2016-02-19 at 06:33 AM
Reply With Quote
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Prescription-glasses.com offers prescription glasses online at discount prices.
All times are GMT +8. The time now is 11:08 AM.


Powered by vBulletin Version 3.8.7
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.