【學習點滴-php】一個bom頭引發的血案

來源:互聯網
上載者:User

事情的起源是一段很普通的代碼:

<?phpsession_start();$_SESSION['test'] = 'test';$_SESSION['name'] = 'name';$data = serialize($_SESSION);...更多後續代碼?>

沒有問題,很簡單的一段設定session的代碼。

但是運行後卻報錯:

Cannot send session cache limiter - headers already sent (output started at...) on line ...

報錯資訊很明顯,就是在session_start()之前有了輸出,導致後面的header發送失敗。

因為很多情況下<?php  標籤之前空格也會被當做header發送出去的,所以先檢查這個。

仔細檢查一下,沒有空格,沒有echo ,沒有print等導致輸出的問題,那麼到底是什麼問題呢?

應該有很多人都想到了,bom頭。

對,這裡就是bom頭搞的鬼。

那麼什麼是bom頭呢?

BOM: Byte Order Mark就是一個位元組順序標籤,類似一個標記,又叫簽名, BOM簽名的意思就是告訴編輯器當前檔案採用何種編碼,方便編輯器識別,但是BOM雖然在編輯器中不顯示,但是會產生輸出,就像多了一個空行。一般的編碼集中並不會出現bom頭,unicode編碼集中會出現。常見的bom頭是:【摘錄自:http://www.cnblogs.com/chengmo/archive/2010/10/30/1864004.html】  UTF-8    ║ EF BB BF   UTF-16LE ║ FF FE (小尾)  UTF-16BE ║ FE FF (大尾)  UTF-32LE ║ FF FE 00 00   UTF-32BE ║ 00 00 FE FF為什麼bom頭會產生亂碼?【摘錄自:http://www.cnblogs.com/chengmo/archive/2010/10/30/1864004.html】有bom頭的儲存或者位元組流,它一定是unicode字元集編碼。到底屬於那一種(utf-8還是utf-16或是utf-32),通過頭可以判斷出來。由於已經說過utf-16,utf-32不指定bom頭,解析程式預設就認為是ansi編碼,出現亂碼。而utf-8指定或者不指定程式都可判斷知道對於的字元集編碼。問題就出在這裡,可能有的應用程式(ie6瀏覽器),它就認為如果utf-8編碼,就不需要指定bom頭,它可以自己判斷,相反指定了bom頭,它還會出現問題(因為它把頭當utf-8解析出現亂碼了)。這裡不了,cnblogs裡面談這個比較多,目前ie6會出現問題。其它ie7+,firefox,chrome不會出現,會忽略掉bom頭。統一解決辦法是:存為utf-8編碼是,不需要加入bom頭,其它utf-16,utf-32加入。

知道了這個,解決方案就很明顯了:把utf-8的bom頭去掉即可。

方式就是檔案編碼格式選擇utf-8無bom。

另摘錄一個網上找來的去除bom頭的代碼:

<?phpif (isset($_GET['dir'])){//config the basedir    $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=red>BOM found,automatically removed.</font>");        }else {            return("<font color=red>BOM found.</font>");        }    }    elsereturn ("BOM Not Found.");}function rewrite ($filename,$data) {    $filenum= fopen($filename,"w");    flock($filenum, LOCK_EX);    fwrite($filenum,$data);    fclose($filenum);}?>

另外一個常見的bom頭的地方時xml檔案。解析失敗的話,有很大一部分原因是這個。

Error on line 1 of document  : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog.

此時只要去掉bom頭就行了。

特此記錄下來,希望對大家有協助。

(2011-11-03  happyelements)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.