BOM頭是php開發過程中最常見的問題。下面宅鳥就如果解決這類問題給出方法,在這裡感謝一下文字描述的作者小囧,因為需要引用他的描述,小囧同志說的非常好,正是宅鳥需要闡述的…
BOM: Byte Order Mark
UTF-8 BOM又叫UTF-8 簽名,其實UTF-8 的BOM對UFT-8沒有作用,是為了支援UTF-16,UTF-32才加上的BOM,BOM簽名的意思就是告訴編輯器當前檔案採用何種編碼,方便編輯器識別,但是BOM雖然在編輯器中不顯示,但是會產生輸出,就像多了一個空行,如果您在修改任何PHP檔案後發生:
* 不能登入或者不能登出;
* 頁頂出現一條空白;
* 頁頂出現錯誤警告;
* 其它不正常的情況。
則多半是編輯器的問題。
本程式採用UTF-8編碼。現在幾乎所有的文字編輯軟體都可以顯示並編輯UTF-8編碼的檔案。但是很遺憾,其中很多軟體的表現並不理想。
類似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。)
以下是程式解決方案(程式碼作者的作者應該受到尊重在此給出其連結):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
<?php /*檢測並清除BOM*/ 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 );
}
}
} //end while
closedir ( $dh );
} //end if($dh
} //end function
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." );
} //end function
function rewrite( $filename , $data ){
$filenum = fopen ( $filename , "w" );
flock ( $filenum , LOCK_EX);
fwrite( $filenum , $data );
fclose( $filenum );
} //end function
?> |
本文轉自birdinroom 51CTO部落格,原文連結:http://blog.51cto.com/birdinroom/1343945,如需轉載請自行聯絡原作者