如何調試PHP程序

如何調試PHP程序

發表於 2011-11-13    60350 次查看

調試的定義:經過必定方法,在程序中找到並減小缺陷的數量,從而使其能正常工做。
這裏說一些如何調試PHP程序的經驗。php


1、PHP自帶的調試功能
mysql

一、自帶的報錯功能web

兩個名詞:開發環境是開發人員在進行開發和調試的環境,生產環境是最終客戶在用的線上環境;
開發環境和生產環境要分開設置報錯功能。sql

(1)開發環境
開發環境須要打開報錯,如下是php.ini的配置項及其說明:數組

; This directive sets the error reporting level.
; Development Value: E_ALL | E_STRICT (Show all errors, warnings and notices including coding standards.)
error_reporting = E_ALL | E_STRICT網絡

; This directive controls whether or not and where PHP will output errors,
; notices and warnings too. Error output is very useful during development.
; Development Value: On
display_errors = Onsocket

這樣你在開發過程當中,能第一時間發現錯誤。ide

即便是一個低等級的報錯「Notice: Undefined variable: a in E:\phpspace\test.php on line 14」,但一個未定義的變量的使用每每暗藏着bug。函數

你會問,若是我引進了開源的類庫,他們拋出一堆的低等級錯誤怎麼辦?通常代碼質量好的類庫,也沒有「Notice」級別的報錯的。因此這也是鑑別一個類庫質量的方法。工具

(2)生產環境

生產環境不能直接將錯誤輸出,而是記入日誌,如下是php.ini的配置項及其說明:

; It could be very dangerous in production environments.
; It's recommended that errors be logged on production servers rather than
; having the errors sent to STDOUT.
display_errors = Off

; Besides displaying errors, PHP can also log errors to locations such as a
; server-specific log, STDERR, or a location specified by the error_log
; directive found below. While errors should not be displayed on productions
; servers they should still be monitored and logging is a great way to do that.
; Production Value: On
log_errors = On

; Log errors to specified file.
error_log = /path/to/php_error.log

固然日誌寫到文件裏只是一個選擇,還有其餘配置可參考手冊。

生產環境是給客戶提供服務的,你不可能在上面進行斷點、打印輸出等操做,因此日誌是不錯的選擇。

二、其餘一些語言特性、功能的使用

(1)少用錯誤控制運算符「@」

其的做用是,將「@」放置在一個PHP表達式以前,該表達式可能產生的任何錯誤信息都被忽略掉。

若是一個缺陷發生在這個表達式中,從PHP的輸出中看不到任何錯誤,這增長了調試的難度。因此能不用則不用。

(2)有些函數自帶有debug功能

好比這行代碼:

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);

開發者調試時已經肯定,$fp爲空,鏈接失敗,是這一行有問題,可是爲何鏈接失敗?

函數是php自帶的,沒法進行更深刻的調試。因此通常這樣的函數(主要是網絡通訊類的),會本身提供調試參數:$errno和$errstr。你能夠加一句:

if (!$fp) echo "$errstr ($errno)<br />\n";

就能看到鏈接失敗的緣由了。

這些函數有:fsockopen,pfsockopen,stream_socket_server,stream_socket_client 等。

還有些函數是調試一個功能用的,好比:mysql_errno,socket_last_error,socket_strerror 等。

這些只須要了解下,碰到能想到用便可。

2、引進調試工具

在遇到複雜問題時,能夠藉助調試工具。比較成熟的有Xdebug、ZendDebugger。

以Xdebug爲例,它可以:控制打印輸出的樣式和數組層級、堆棧式的追蹤錯誤、追蹤函數調用、代碼執行覆蓋分析、程序的概要分析(Profiling)、遠程調試。詳見:http://xdebug.org/docs/

Xdebug前兩個功能是對PHP原有的調試功能作了改進,更方便調試。

複雜的問題,調試不出來的,多是業務上的的問題,下面也有說業務邏輯的調試。

3、調試業務邏輯錯誤

當PHP腳本跑起來,沒有任何錯誤,只能說它沒有語法上的錯誤,可是不能說明它業務邏輯上沒錯誤。

不少業務邏輯的錯誤並不會反映在語法錯誤上,但調試的思路和PHP自帶調試功能差很少。

下面是一些方法。

一、最基本的調試方法

先肯定兩個東西:程序預期的結果、程序如今的不符合預期的結果;
尋找與兩種結果相關的代碼片斷;
閱讀這些代碼片斷,嘗試以「肉眼」找出錯誤;
找不出,則須要輸出一些關鍵變量,經過檢查它們的值是否正確來判斷是哪裏發生了錯誤;
若干次嘗試,最終你能夠肯定錯誤發生在哪一個點。

你也能夠藉助Xdebug等工具,查看變量值的變化,或者設置斷點進行調試。

二、記錄運行日誌

有些複雜或特殊的業務,用上面的方法不合適,好比:一個不能被打斷的後臺運行腳本。這些狀況下記錄運行日誌比較合適。

記日誌的點要有所選擇,除了業務上比較重要的點,一般容易出錯的地方有:網絡鏈接和通訊、系統權限問題等。

三、單元測試

以代碼測試代碼,而不是像第一點同樣調試完會把測試代碼丟掉。以測試驅動開發。

這個話題比較大,但適合放這裏提一下。有興趣的同窗能夠去了解。

4、調試非功能性的錯誤

非功能性錯誤,好比:內存溢出致使程序掛掉了、效率有問題致使程序很是慢、死循環了等等。

這些問題,用「肉眼」檢查代碼效率過低了。

因此能夠藉助調試工具作程序的概要分析(Profiling),從中檢查出程序的瓶頸所在。

相關文章
相關標籤/搜索