2014-12-22

PHP 遇到 Cannot send session cache limiter - headers already sent

PHP 專案在本機正常,到了正式機就鬼打牆,「本機沒事啊」,這應該是工程師最常講得一句話吧。

出現以下的錯誤:
headers already sent (output started at ...config.php:1) in ...config.php on line 5
程式看了半天,session_start() 也搬到不能再前面了,還是爛去。

Google 了半天,最後,還是它 xxx 的 Windows 問題,比爾先生,您為何要造這麼多孽呢?

我的 config.php 沒問題,上到正式機,PM 打開 config.php 修改設定後,就會出現以上的問題。

問題在,PM 是用記事本編輯的,然後多事的 Windows 就在檔案最前面加上 BOM,懶得去瞭解這是什麼鬼。

BOM 在大部分的 php 功能裡不會有什麼傷害,直到用了 header(...) 就爆了!

因為 BOM 是純文字,看不到的純文字,會直接輸出,然後 php 用 header(...) 時就有意見了,在呼叫 header(...) 之前,不可以有任何輸出,否則就是上面那段錯誤訊息出來說嗨。

兩個解法:

第一,修改 php 設定,允許 header(...) 之前輸出,加上 output_buffering = 4096 ,再重起 Apache,就可以了。

第二,用比較厲害的文字編輯器,我是用 EditPlus,開啟然後另存,可以在 Encoding 選項裡看到 UTF-8 與 UTF-8 + BOM,選 UTF-8 就沒事了。


7 則留言:

  1. 這個問題有遇見過,直接給他個noteped++ 完敗
    記得沒錯的話,bom是指說要用什麼編碼去讀取檔案用的

    回覆刪除
    回覆
    1. 那我就好奇了,除了 Windows 以外,其他軟體不需要 BOM 就可以用正確的編碼開啟,是用猜的嗎?

      刪除
  2. http://www.zhihu.com/question/20167122
    因為utf-8本來就不需要標記bom(是可標可不標),而apache讀取時,是以標準(即無標頭)來讀取文件的,所以才會出現error

    回覆刪除
  3. http://blog.roodo.com/rocksaying/archives/1096340.html
    另外,好像在php6裡就會修正這個問題了(畢竟不是每台電腦都有裝其他的editor)

    回覆刪除
    回覆
    1. 嗯,萬能的 PHP 是應該這麼做才對,學了 PHP 才知道寫 Java 好累。

      刪除
    2. 學了php才覺得java的嚴謹是真正的好,因為在決定每一個變數及函式時都已決定好每一個回傳是什麼型,而不是要再寫一個去判斷類型(常常用foreach去判斷類型)

      刪除