服務器出現500錯誤或空白的時候,讓PHP顯示錯誤信息


用PHP開發程序時,如果服務器出現500的時候(有時甚至不報錯直接顯示空白),如果無法知道究竟是什么原因,就無法進行調試。

要讓PHP顯示錯誤信息,可以從PHP配置文件 (php.ini)或PHP程序文件入手,另外,如果與IIS整合的時候,還必須考慮web.config文件。

 

如果是與IIS整合的方式,則需要修改web.config文件,對其中的<system.webServer>項添加<httpErros>條目:

<system.webServer>
    <httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" />
</system.webServer>

 

php.ini配置文件中涉及的修改:

注意修改完配置文件后需要重啟web服務器(如果是IIS,可以通過IIS管理器中的“FastCgi設置”監聽php.ini的更改,這樣可以不用重啟)。

 

1、error_reporting = E_ALL       

 

error_reporting 意思是“錯誤-報告形式,指定了出錯時是否顯示到瀏覽器記錄到日志文件的方式。

設置錯誤記錄的級別,E_ALL為報告所有 PHP 錯誤,通常在調試錯誤的時候設置為此(也可以設置為-1或E_ALL^警告過期等)。

生產環境為了安全問題,建議設置為0。

 

 

error_reporting的默認值E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED(PHP5.5.16版,其他版本可能各不同)

 

其它常見的值為:E_WARNING,E_NOTICE,E_DEPRECATED,這些通常作為排除形式,在非調試情況下與E_ALL搭配使用,比如:

E_ALL  ^  E_DEPRECATED  -報告所有錯誤但不報告過期(或即將過期)的提示,通常用於舊程序上使用了即將過期方法產生錯誤時,比如使用了mysql_connect導致過期錯誤500。

E_ALL ^  E_NOTICE  -報告所有錯誤但不報告警告,通常可以解決Undefined Index或Undefined Variable等提示。 

 

 

如果error_reporting=0,代表着不顯示、不記錄任何錯誤。

如果error_reporting=E_ALL排除某些形式時,代表着顯示、記錄所有出錯信息,但不顯示、不記錄這些排除了的。

 

不想顯示出錯信息,在程序中使用了ini_set("error_reporting",0),但仍然顯示出錯信息的情況:

出現解析錯誤(語法問題),此時會導致php.ini中的優化級高於PHP源文件各項,所以如果php.ini中的error_reporting=On,則仍然會報錯。

 

2、display_errors = On    

display_errors 名如其義,“顯示-出錯信息”,它針對的是輸出端(這里是瀏覽器)的顯示與否。

設置為On時,將會對error_reporting所設置的相應級別的出錯信息,顯示到瀏覽器上

(但瀏覽器顯示出錯的信息是否真的來源於它,還需要考慮log_errors與error_log,見后邊)。

 

設置為Off時,將不輸出相應出錯信息到瀏覽器

(但瀏覽器是否絕對不輸出出錯信息,在error_reporting為On時,還需要考慮log_errors與error_log,見后邊)

 

display_errors受到error_reporting的限制:

如果error_reporting為0,則display_error設置將失效。

如果error_reporting為排除某些級別,display_error設置為On時將排除指定級別錯誤信息的顯示。

 

對於“想要顯示錯誤信息”時,直接配置error_reporting=E_ALLdisplay_errors=On 一般來說是沒有問題的。如果有,則會是:

(1) “頁面空白,但顯示狀態為200正常” - 通常是程序正常輸出前遇到Fatal Error(如擴展未開啟,調用了未定義函數),但使用了@屏敞掉了錯誤並中斷。

 

(2) “只顯示錯誤信息,但沒有顯示程序中出錯前的其它輸出的內容” - log_errors被設置為On,但error_log日志文件沒有權限或路徑錯誤造成的。可以設置log_errors為Off或者設置正確有權限的error_log路徑。

 

(3) "只顯示HTTP500內部服務器錯誤,但沒有直觀的具體的錯誤信息” - IE瀏覽器的設置問題 。如果是IE瀏覽器或者是在IE模式下運行,可以切換為其它非IE瀏覽器或非IE模式試試,也可以在瀏覽器 “ 工具  》 Internet屬性  》  高級   》 設置  ”  中,將“顯示友好HTTP錯誤信息” 中的勾選去掉。

 

 

3、log_errors = On

log_errors 名如其義,“記錄-出錯信息”,它表示的是日志文件對出錯信息的記錄與否

設置為On時,代表將相應級別的錯誤記錄到日志文件,如果為On,則必須與error_log項相搭配使用,並且注意error_log的配置問題,否則可能對瀏覽器輸出有影響。

設置為Off時,代表着不在日志文件中記錄出錯信息。設置為Off時,將不會對瀏覽器的輸出有影響。

 

4、error_log = c:/wamp/php/php5.5.16/error.txt

error_log 意思是“錯誤-日志文件,指定了出錯信息如果需要記錄時,所記錄到日志文件的位置。

error_log 配置錯誤日志文件位置,通常用於在生產環境下不方便在瀏覽器顯示錯誤時,可以將錯誤記錄到文件,也可用於記錄瀏覽器不能顯示的某些特定的錯誤/警告,如:PHP Warning:  PHP Startup: Unable to load dynamic library。

默認為被注釋掉(即為空,它是權限問題造成的原因之一)。

error_log配置時可以使用根路徑、物理路徑、相對路徑等形式,如:

(1) error_log = /xxx/xx/error.txt  - 相對於運行文件所在的磁盤根目錄的路徑,windows與linux系統都中可以如此設置。

(2) error_log = error.txt  或 ../error.txt 等  - 相對於正在執行的PHP文件運行文件路徑,通常不這么設置。

(3) error_log = c:/wamp/php/php5.5.16/error.txt  - 硬盤路徑,windows系統中通常使用的形式。

 

 

當log_errors為On且配置的日志文件沒有權限時,不管display_error為On還是Off,錯誤信息都不寫入日志文件,會直接輸出到瀏覽器上 (這一點在“不想顯示錯誤信息”時要特別注意)

error_log權限問題,在以下情況會出現權限問題(沒有權限):

(1)文件所在的目錄路徑不存在,沒有權限。

(2)位置正確,但文件確實沒有權限

(3) error_log 沒有配置(即被;號注釋了)-這個是最常見的導致出錯日志信息反輸到瀏覽器的權限問題

 

 

至此,理解了這4個配置,並進行正確設置,就能顯示或不顯示、記錄或不記錄出錯信息。

除了可以在php.ini中對此4項進行設置,也可以在php文件中使用代碼進行設置:

php文件配置瀏覽器顯示錯誤:

error_reporting(E_ALL); 
ini_set('display_errors','On'); 
ini_set('log_errors','On'); 
ini_set('error_log','/log.txt');// 配置了正確的有權限的日志文件路徑

 

php文件配置瀏覽器不顯示錯誤(但日志文件記錄錯誤):

 

error_reporting(0); 
ini_set('display_errors','Off'); 
ini_set('log_errors','On'); 
ini_set('error_log','/log.txt');// 配置了正確的有權限的日志文件路徑

 

 

一般情況下php文件對四個相關配置的設置優先級高於php.ini,並且不需要重啟web服務器就能看到效果。

但如果出錯屬於語法錯誤時,php文件處理不運行狀態,這時php.ini的設置的優先級更高。

 

 

判斷瀏覽器上顯示的錯誤是display_errors的還是log_errors的:

display_errors=on 作用下的幾個顯示例子(有加粗效果):

Parse error: syntax error, unexpected ';'  

頁面不執行代碼僅顯示錯誤輸出(無法通過@屏敞錯誤輸出)

 

Fatal error: Call to undefined function   

頁面執行到錯誤處,如果有輸出則顯示輸出,之后顯示錯誤輸出,並且中斷后續執行(如果有@可以屏敞該級別的錯誤輸出,但仍然會中斷后續執行)。

 

Notice: Undefined variable:        

頁面執行到錯誤處,如果有輸出則顯示輸出,之后顯示錯誤輸出,但不中斷后續執行(如果有@可以屏敞該級別的錯誤輸出)。

 

 

log_errors=on 作用下的幾個顯示例子(無加粗效果,有PHP前綴):

PHP Parse error: syntax error, unexpected ';'     

頁面不執行代碼僅顯示錯誤輸出(無法通過@屏敞錯誤輸出)

 

PHP Fatal error: Call to undefined        

頁面執行到錯誤處(有輸出的話也不進行任何輸出),之后僅顯示錯誤輸出,並且中斷后續執行(如果有@可以屏敞錯誤輸出同時將之前程序執行輸出也顯示出來,但仍然會中斷)。

 

PHP Notice: Undefined variable:        

頁面執行到錯誤處(有輸出的話也不進行任何輸出),之后顯示錯誤輸出,但不中斷后續執行(只有頁面中的所有出錯都被@屏敞或者中斷前的出錯都被@屏敞,程序中的正常echo輸出才能顯示。瀏覽器會顯示所有的非中斷錯誤提示,直到中斷)。 

 

說明:

log_errors=On起作用的原因:error_log沒有配置或路徑錯誤或權限問題

error_log沒配置或不正確時,log_errors=On、display_errors=Off時,瀏覽器顯示無加粗的有PHP前綴的錯誤。當然,當error_log正確配置時,就沒有這種情況。

只讓display_errors=on起作用的話,可以設置log_errors=Off , 也可以設置log_errors=On 並且 error_log=正確的有權限的文件

通過瀏覽器的顯示效果或輸出、中斷效果,可以大概知道php.ini中對display_errorlog_errors的配置情形。

通過@可以屏敞錯誤輸出,並且針對log_errors=On起作用的程序輸出也可以進行輸出控制。

 

 

 

 

導致頁面空白(即響應碼200正常,但不輸出任何html)的兩種情形:

 

[1].遇到Parse error之類的編譯錯誤,但設置了瀏覽器不進行錯誤顯示,如:

php代碼示例:

 

<?php
x(;
?>

 

 

php.ini示例-形式一:

 

error_reporting = E_ALL
display_errors = Off
log_errors = Off

 

php.ini示例-形式二:

error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = 正確的有權限的路徑

php.ini示例-形式三:

error_reporting = 0

php.ini示例-形式四:

error_reporting = E_ALL ^ E_PARSE

 

[2].程序有輸出之前遇到Fatal error之類的中斷錯誤,且用@進行了抑制(此時與display_errors、log_errors都無關),如:

php代碼示例:

 

<?php
@x();
echo 'begin print msg!'; //不會輸出,已中斷 ?>

 根據上邊形式,可以知道當MYSQL擴展沒有開啟時,以下代碼執行,頁面顯示空白:

<?php
//此前沒有任何輸出操作
$conn = @mysql_connect('localohst','root','root') or die('連接數據庫出錯!'); echo 'query ......'; //不會輸出,已中斷 $conn->query(); ?>

注意@號可以牽連到該代碼執行范圍內的調用到的其它所有東西(如被調用的函數),所以對於用戶自己的函數的調用,最好不要進行@調用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM