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

  • 内容
  • 相关

HP文件头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=redBOM found, automatically removed./font"); 
}else { 
return ("font color=redBOM 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:
?phpif(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=redBOM found, automatically removed./font"); 
}else { 
return ("font color=redBOM found./font"); 
} 
}else return ("BOM Not Found."); 
} 
function rewrite ($filename, $data) { 
$filenum = fopen($filename, "w"); 
flock($filenum, LOCK_EX); 
fwrite($filenum, $data); 
fclose($filenum); 
} 
?>


本文标签:

版权声明:若无特殊注明,本文皆为《鬼少》原创,转载请保留文章出处。

本文链接:PHP文件头BOM带来的困惑(frameset无法显示,头部一行空白) - http://tv1314.com/post-6.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注

00:00 / 00:00
顺序播放