標籤:

有哪些 PHP 調試技巧?


我目前遇到的最讓我稱讚的debug方式是:xdebug的

xdebug_start_trace();
/* 業務代碼 */
xdebug_stop_trace();

他解決了我長久以來一個代碼調試問題:比如有以下幾個場景:

1、一個有幾百行的函數,裡面有很多return,現在函數異常返回了,但是我不知道是從哪一行返回的,這時候呢,我一般的做法都是每一行echo();die();太費事了。

2、接觸一個新的框架,代碼執行出現異常,怎麼辦呢,肯定也是一行一行的echo();die();

3、想學習一個新框架,想知道代碼的執行軌跡:執行了哪些類、調用了哪些類的方法,等等。

現在呢,xdebug的代碼跟蹤,能幫我們輕鬆解決上面的問題。

xdebug的安裝(網上我看到了很多的都是在說xdebug、phpstorm、chrome咋配合起來遠程調試,搞得大家好像覺得xdebug用起來那麼費事,那麼高級,其實沒必要):

1、安裝php xdebug擴展(不再細說)

2、配置:這裡只講代碼跟蹤相關的配置:

cat /etc/php.d/xdebug.ini
extension=/usr/lib64/php/modules/xdebug.so
;代碼跟蹤日誌文件位置,注意要先新建這個traces目錄,並設置777
xdebug.trace_output_dir = /tmp/traces
;代碼跟蹤日誌文件格式
xdebug.trace_output_name = trace.%c.%p
;trace中顯示函數的參數值,這個很有用,待會細說
xdebug.collect_params = 4
xdebug.collect_includes = On
xdebug.collect_return = On
xdebug.show_mem_delta = On
;var_display_max_depth這個參數也很有用。用來設置數組或者對象顯示的最大層級。
;默認是3。參見官方文檔的說明:Controls how many nested levels of array elements
;and object properties are when variables are displayed
;with either xdebug_var_dump(), xdebug.show_local_vars or through Function Traces.
xdebug.var_display_max_depth = 2

安裝好之後,代碼執行明細(trace),就存放在/tmp/traces目錄下了:

我截取一段trace日誌,大家看下,就能感知到這個用法的方便了:

1、顯示了參數的值:就這一點,我想就會節省我們phper很多的調試時間(默認不顯示參數值,只顯示調用的函數。需要添加xdebug.collect_params這個配置)

2、顯示了代碼的執行軌跡。類似於c語言的單步調試吧。

就這些了,反正用了xdebug,我是覺得debug的時候節省了大量時間,分享給大家,希望對你們也有幫助。

ps:如果大家都xdebug的安裝有困惑,可以參考http://www.ibm.com/developerworks/cn/opensource/os-php-xdebug/index.html

-------以下是2017.12.08補充-------

再補充一種調試方法:

利用symfony/var-dumper包中的dump()函數,格式化輸出變數

效果如下:

當然,很多框架裡面都內置了類似的列印函數,這裡只所以推薦,更重要的一個原因是:可以通過全局安裝,實現dump()函數對所有項目可見,無需在項目中引入任何代碼庫。

安裝方法如下:

1、執行 composer global require symfony/var-dumper ,全局安裝var-dumper包,默認會安裝到${HOME}/.config/composer目錄。

2、在php.ini文件中加入一行:

auto_prepend_file = ${HOME}/.config/composer/vendor/autoload.php
//auto_prepend_file可以簡單地理解成:執行所有的php代碼之前先include你指定的文件

從此以後,在你任意的php項目中調用

dump($var);
//調用dump函數的時候,會觸發autoload,實現函數、類的自動載入。
//關於composer autoload,不明白的可以參考
//https://laravel-china.org/topics/1002/deep-composer-autoload

就可以實現上述的列印效果了。


技巧談不上,只不過很多PHP開發者忽略了Xdebug自身就具備的強大功能,樓上已經有人提及.

Xdebug: PHP debugger(調試器) profiler(探查器)

說到PHP調試,Xdebug不要太強,連ZendDebugger都退位讓賢了.

遠程調試只不過是Xdebug的一個功能,Xdebug還支持trace代碼跟蹤和profile性能探查.

profile日誌能記錄函數的執行耗時和調用關係等信息.

trace日誌就牛逼了,能夠記錄代碼執行流程,包括:

時間索引,內存使用,內存增量,調用層級,函數名稱,函數參數,代碼所在文件名,代碼所在文件行等信息.

也就是PHP開發者只要學會看Xdebug這個trace日誌,

還用什麼IDE打斷點,看看日誌就知道代碼的執行流程和數據的傳遞流程.

xdebug.trace_format = 0

Xdebug: Documentation

格式0表示:

shows a human readable indented trace file with:

time index: 時間索引

memory usage: 內存使用

memory delta: 內存增量(需要開啟:show_mem_delta)

level: 層級(調用關係,通過縮進呈現)

function name: 函數名稱

function parameters: 函數參數(需要開啟:collect_params)

filename: 代碼所在文件名

line number: 代碼所在文件行

另外:

-&> 表示函數調用.

&>=&> 表示函數返回值.

Swoole服務啟動時會生成2個Xdebug調試文件:

debugger: /opt/php/xdebug/trace.{$xxx}.xt (可以使用Geany查看,配合列編輯功能,方便查看縮進層級)

profiler: /opt/php/xdebug/cachegrind.out.{$pid} (可以使用kcachegrind查看)

文件trace.{$xxx}.xt里記錄了代碼執行日誌,包括函數調用,參數,返回值等信息.

文件cachegrind.out.{$pid}里記錄了函數的執行耗時和調用關係等信息.

手動觸發跟蹤:

方式1: URL參數 XDEBUG_TRACE=foobar (適用於PHP-FPM,不適用於Swoole)

xdebug.auto_trace = Off

xdebug.trace_enable_trigger = On

xdebug.trace_enable_trigger_value = "foobar"

方式2: 調用Xdebug函數觸發跟蹤

配置:

xdebug.auto_trace = Off

xdebug.trace_enable_trigger = On

觸發:

xdebug_start_trace();

// 目標代碼區間,比如一個函數

xdebug_stop_trace();

所以說不是非得用調試器前端才能進行代碼調試.

比如使用編輯器進行PHP開發時,

代碼裏手動調用Xdebug函數觸發跟蹤,然後分析調試日誌,

就能看到代碼執行流程及函數參數和返回值等信息.

用這招查看函數體中代碼的返回位置,特別方便.


1、最簡單經典的var_dump()

2、配置error_log,能夠解決很多疑難雜症

3、firebug + firephp或者chrome + chromephp


eclipse + PDT或者Zend studio的斷點調試都很不錯


我比較喜歡笨方法print_r + exit來調試代碼。


我要掛一個Xdebug吹 @eechen ;聽說此人臭名遠揚,但沒成想能被這樣的和諧辭彙主動拉黑,內心感覺就像是吃了不可名狀物。

我們親愛的友善詞 @eechen 認為,可以使用日誌來替代 IDE 下斷點功能。但字裡行間的意思是,「有了日誌就不需要下斷點了」。

然後我就被拉黑了。但看這個評論,誒,我們親愛的友善詞同學,你真的用過 Xdebug 嗎?可是你明明也知道 Xdebug 的遠程調試功能嘛。

如圖,為 PHPStorm 配合 Xdebug 的遠程調試功能進行單步調試的截圖。

XDebug的文檔見Xdebug: Documentation ,在這裡它列出了不同的 IDE 應該如何配置斷點功能。通過 Remote Debugging, PHP可以達到類似其他語言的 IDE 開發體驗。

我平常喜歡使用的編輯器 Visual Studio Code 自然也有相應插件: felixfbecker/vscode-php-debug

親愛的友善詞 @eechen ,現在你知道,Xdebug作者和你誰聰明了嗎?如果日誌真的那麼萬能,那麼為什麼還要開發這個功能呢?

關於打Log和單步調試這兩種調試手段誰更好,可以參見:列印日誌 (log) 是比單步跟蹤 (debugger) 更好的 Python 排錯手段嗎?


php調試指南:http://heiyeluren-doc.googlecode.com/files/PHP-Debug-Manual-public.pdf

挺薄的一個冊子,講的不錯。


xdebug


php 5.6 新增 phpdbg,使用方法上類似於gdb。

官方貨


exit(var_dump());

print_r();

file_put_contents($log_path,var_export(xxx,true));

自定義報錯類,參考YII的調試輸出,和報錯輸出。

IDE 的調試功能。


調試Ajax的時候Chrome和Firefox的調試工具簡直神器…


xdebug+WinCacheGrind


可以用一些調試工具,多輸出,還有就是利用注釋。


XHProf 吧,

FaceBook開源出來的神器,PHP輕量級調試工具,可在生產環境中使用。

1. Inclusive Time :包括子函數所有執行時間。

2. Exclusive Time/Self Time:函數執行本身花費的時間,不包括子樹執行時間。

3. Wall Time:花去了的時間或掛鐘時間。

4. CPU Time:用戶耗的時間+內核耗的時間

5.Inclusive CPU:包括子函數一起所佔用的CPU

6.Exclusive CPU:函數自身所佔用的CPU


你們都太弱了,VS2013調試PHP才是最威武霸氣的選擇。


一般情況,echo + print_r + exit + /* ...*/

實在搞不定,就上 debug_backtrace (用這個函數生成自己的錯誤日誌非常好用)


可以結合;ide 進行斷點調試

phpstrom+xdebug + chrome(debug helper) or FF (easy xdebug)


一般需要調試分以下幾種:

1、代碼拼寫錯誤,這個用一般IDE編輯器就能解決

2、邏輯錯誤,這個是最頭疼的,大多時候是一步一步var_dump,一步一步exit,碰到post的數據,就更頭疼

邏輯錯誤大多數是數據有問題,比如,大小寫敏感、非空數據檢測。。。。等等

所以我一般在數據的讀寫上都加上debug,默認是關閉,可能通過get/post/config來設置是否打開debug,在當前頁面輸出所有讀寫數據,基本上一眼就能定位到問題所在

資料庫操作、文件讀寫、遠程讀取、緩存操作 均使用自己封裝過的函數


搜一下「php調試技術手冊」


debug_backtrace。


推薦閱讀:

php學到什麼程度就可以就業了?
有哪些為了精通 php 而一定要自己實現一次的例子? demo?
為什麼現在很多框架都用Composer來安裝,增加了學習難度?
php查詢資料庫用了一個c寫的擴展,這樣做有什麼好處呢?

TAG:PHP | PHP開發 |