学习笔记

Study notes

BOM (隐藏字符)

云逐梦23942017-09-19 16:24:00返回列表

页面不能顶头,有空隙,原因是:类似WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM)。

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

PHP并不会忽略BOM,所以在读取、包含或者引用这些文件时,会把BOM作为该文件开头正文的一部分。根据嵌入式语言的特点,这串字符将被直接执行(显示)出来。由此造成即使页面的 top padding 设置为0,也无法让整个网页紧贴浏览器顶部,因为在html一开头有这3个字符呢!

最大的麻烦还不是这个。受COOKIE送出机制的限制,在这些文件开头已经有BOM的文件中,COOKIE无法送出(因为在COOKIE送出前PHP已经送出了文件头),所以登入和登出功能失效。一切依赖COOKIE、SESSION实现的功能全部无效。

因此,在编辑、更改任何文本文件时,请务必使用不会乱加BOM的编辑器。Linux下的编辑器应该都没有这个问题。WINDOWS下,请勿使用记事本等编辑器。推荐的编辑器是: Editplus 2.12版本以上; EmEditor; UltraEdit(需要取消‘添加BOM’的相关选项); Dreamweaver(需要取消‘添加BOM’的相关选项)等。

对于已经添加了BOM的文件,要取消的话,可以用以上编辑器另存一次。(Editplus需要先另存为gb,再另存为UTF-8。)不过有时候不会显 。

在程序的根目录运行下面的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);  
    }  
} 

//检查文件中是否存在BOM
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);  
}  
?>


返回
顶部