設定php錯誤訊息

以往,在寫ASP、ASP .net時,當程式有錯誤發生,網頁上就會看到http status 500的錯誤訊息。也曾利用IIS做設定,配合500-100.asp去攔錯誤已產生log,以利後續的問題追查。

可是,在使用 apache + php 時,總覺得很少看到http status 500的錯誤,一般看到的都是php所丟出來的錯誤訊息。記憶中,500的錯誤,好像都是在apache error log中才看過。

同事最近剛好需要得到程式的處理結果。需要利用http status當作後續判斷的依據。因此,當程式發生非預期的錯誤時,要能夠知道異常已經發生。

原本想採用set_error_handler()來處理。不過,忽然想到前陣子整理php.ini時的一個參數 - display_error。該參數會控制php是否會顯示錯誤訊息。不經聯想是否因為這個參數的作用,php為了能在網頁上產出錯誤訊息,因此讓網頁正常執行完,也因此得到http status 200?

以下,則是節錄自php.ini-recommended(php 5.2.x)中對於display_err的說明
; - display_errors = Off [Security]
; With this directive set to off, errors that occur during the execution of
; scripts will no longer be displayed as a part of the script output, and thus,
; will no longer be exposed to remote users. With some errors, the error message
; content may expose information about your script, web server, or database
; server that may be exploitable for hacking. Production sites should have this
; directive set to off.

; Print out errors (as a part of the output). For production web sites,
; you're strongly encouraged to turn this feature off, and use error logging
; instead (see below). Keeping display_errors enabled on a production web site
; may reveal security information to end users, such as file paths on your Web
; server, your database schema or other information.
一般來說只有在開發階段為了DEBUG,才會開啟該參數設定。在正式線上服務的環境中,則是不呈現這些資訊。

以下,則是用個範例來說明。下面程式碼,是正確可以執行的程式
  1. <?php  
  2. $yy=543;  
  3. $xx=$yy;  
  4. echo $xx;  

當我們故意讓程式錯誤時,看看參數display_errors在不同設定下的結果
  1. <?php  
  2. $yy=543;  
  3. $xx=$yy   //故意拿掉; 讓程式錯誤  
  4. echo $xx;  

display_errors = On
得到http status 200,表示網頁正常執行完,頁面上卻會顯示php的錯誤訊息。這可能是一般php開發者所熟悉的畫面。

display_errors = Off
此時得到http status 500的錯誤,但是頁面上不會顯示任何的錯誤訊息。一般的PHP開發者應該很少遇到這樣的狀況。

關於錯誤訊息,在php.ini中還有一個參數 - error_reporting,節錄說明如下…
; - error_reporting = E_ALL [Code Cleanliness, Security(?)]
; By default, PHP suppresses errors of type E_NOTICE. These error messages
; are emitted for non-critical errors, but that could be a symptom of a bigger
; problem. Most notably, this will cause error messages about the use
; of uninitialized variables to be displayed.
不過,這個只是影響要顯示哪種類型的錯誤訊息也就是說,當display_errors = On時,當這個參數的設定才有意義。基本上,線上服務的環境,應該都不要顯示任何訊息在頁面上。至於有哪些項目可以設定?請參考Predefined Constants。(奇怪,列表中怎麼沒有 0 ??)

CodeIgniter就是利用error_reporting,讓開發環境顯示錯誤訊息(error_reporting = E_ALL),線上程式不顯示錯誤訊息(error_reporting = 0)。

留言