1. 程式人生 > >php和bom頭的冤仇 和 如何在linux下使用命令去掉bom頭

php和bom頭的冤仇 和 如何在linux下使用命令去掉bom頭

事情是這樣的 

我有個php檔案的功能是讀取一個二進位制檔案並且echo出來,該檔案本來是圖片檔案,但是我訪問這個php檔案並且寫入到本地硬碟的時候發現並不是圖片格式 

用hexdump 檢視的時候發現檔案首部多了3個位元組
,這不剛好就是bom的utf8編碼的十六進位制表示麼,後來找到原因是因為有個同事包含了一個使用了bom頭的php檔案導致,該位元組在文字編輯器裡是不可見的,著實增加了除錯難度。

導致這個問題的原因是  bom頭是在php的標記<php?>之外的 它的結構類似是這樣的

ef bb bf 
<?php
echo111;
?>

因為php會把標籤外的內容原封不動的輸出,所以導致了這個問題。解決辦法就是去掉該php檔案的bom頭

去除方法:

在windows上如果使用的是phpstom的話,在file選單下面的有 remove bom的選單項

這裡說下linux使用命令取出Bom的方法

對已經是utf8編碼並且擁有bom的檔案去掉bom: sed -i '1s/^\xef\xbb\xbf//' 11.php

相反的
給已經是utf8編碼得檔案 新增bom  :sed -i '1s/^/\xef\xbb\xbf/' 11.php

需要注意的是
這兩條命令只針對 utf8編碼的檔案  對utf16編碼的檔案不能使用 ,因為bom的utf8的編碼表示為ef bb bf三個位元組,但是在utf16編碼下並不是

bom在utf16編碼下的作用是為了說明該檔案儲存的位元組序 ,關於bom的具體作用可以參看wiki,wiki上面已經說的很詳細了

{以下是連結內容  防止連結失效} BOM is nothing more than a nuisance. Detecting and removing it is plain simple. There's a utility called bomstrip that pretty much does what is says and there's the one-liner AWK implementation that you find on stackoverflow (I've added whitespaces for better readability):
awk '{ if (NR == 1) sub(/^\xef\xbb\xbf/, ""); print }' INFILE > OUTFILE
Or a sed version (replaces in place):
sed -i -e '1s/^\xEF\xBB\xBF//' FILE To do this (or just simply detect BOM) recursively in a dir, you'll find tons of ideas in this other stackoverflow article.

For recursively detecting files with a BOM, I prefer this one:
find . -type f -print0 | xargs -0r awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
To recursively remove BOM, you could use something like this:
find . -type f -exec sed -i -e '1s/^\xEF\xBB\xBF//' {} \;
Or a slightly safer variant:
find . -type f -exec sed -i.bak -e '1s/^\xEF\xBB\xBF//' {} \; -exec rm '{}.bak' \; {以上是連結內容  防止連結失效}