php和bom頭的冤仇 和 如何在linux下使用命令去掉bom頭
阿新 • • 發佈:2019-01-24
事情是這樣的
我有個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上面已經說的很詳細了
awk '{ if (NR == 1) sub(/^\xef\xbb\xbf/, ""); print }' INFILE > OUTFILE
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' \;
{以上是連結內容 防止連結失效}