PHP調試跟蹤之XDebug使用總結:
Xdebug是一個開源的PHP程式調試工具,可以使用它來調試、跟蹤及剖析器運行狀態。當然,Xdebug需要結合PHP的編輯工具來打斷點、跟蹤、調試及分析,比較常用的PHP的Xdebug調試環境:Vim +Xdebug。
· 安裝配置
· 調試環境
· 跟蹤分析
· 注意事項
· 遇到問題
一、安裝配置
1、安裝
Xdebug的安裝是作為PHP的拓展而存在的,所以可參考PHP拓展文章:
http://blog.csdn.net/why_2012_gogo/article/details/51120645
2、配置
php.ini:
[xdebug]
;基本調試配置
xdebug.auto_trace = on
xdebug.collect_params = on
xdebug.collect_return = on
xdebug.profiler_enable = on
xdebug.profiler_output_dir ="/php/ext/xdebug_profilers"
xdebug.trace_output_dir = "/tmp/ext/xdebug_traces"
;遠端偵錯設定
xdebug.remote_enable = on
xdebug.remote_host = localhost
xdebug.remote_port = 9010
xdebug.remote_autostart = on
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20131226/xdebug.so
NOTE:
上面羅列的是最為常用的配置選項,至於其他配置選項及對應的含義,請參考:
https://xdebug.org/docs/all_settings#auto_trace
二、調試環境
Vim + Xdebug:
1、下載
http://www.vim.org/scripts/script.php?script_id=1929
2、配置
$ cd ~
$ sudo mkdir ~/.vim
將上面下載的xdebug的plugin中檔案複製到.vim下:
$ sudo cp –r /php/ext/plugin .
在使用者主目錄下建立.vimrc檔案:
$ sudo touch /usr/share/vim/vimrc ~/.vimrc
$ sudo vim ~/.vimrc
為.vimrc添加以下內容:
let g:debuggerPort = 9010(該連接埠必須與xdebug.remote_port相同)
let g:debuggerMaxDepth = 5(代表數組調試深度配置)
NOTE:
vimrc檔案是vim的主要設定檔,它包含兩個版本:全域版本和使用者版本,我們建議修改使用者版本的vimrc設定檔,這兩種版本的路徑可在vim普通模式下查看,如下:
全域版本路徑查看:
$ sudo vim
$ :echo $VIM
路徑地址:/usr/share/vim
使用者版本路徑查看:
$ sudo vim
$ :echo $HOME
路徑地址:$HOME(pwd ~)
注意:
g:debuggerPort的連接埠號碼,必須與xdebug.remote_port相同;
g:debuggerMaxDepth代表的是指令碼調試的最大深度層次;
最後,修改完php.ini、.vimrc配置後,記得重啟php-fpm。
3、調試
A、準備一個php檔案
<?php
$value = '馬上使用XDebug偵錯工具,你準備好了嗎';
echo $value;
?>
將上面的檔案放入到你的Web根目錄下,我的訪問地址是:
http://localhost/xdebug.php 測試下是否正常顯示。
B、使用vim開啟php檔案
使用vim普通模式開啟php檔案,移動滑鼠箭頭到欲調試的那行,輸入:
$:Bp
截圖如下:
然後,按下F5(Mac:Fn+F5),開始監聽調試事件,這時在編輯窗底部提示5秒內訪問要調試的php檔案,例如:
http://localhost/xdebug.php? XDEBUG_SESSION_START=1
截圖如下:
對於調試中的操作在下面附加上:
| 類型 |
功能 |
說明 |
| <Command Mode> |
|
|
| :Bp |
toggle breakpoint |
斷點標記 |
| :Up |
stack up |
|
| :DN |
stack down |
|
| <Normal Mode> |
|
|
| ,e |
eval |
|
| <Function Keys> |
|
|
| F1 |
resize |
調整視窗大小 |
| F2 |
step into |
調試步進入 |
| F3 |
step over |
調試步進入下一標記 |
| F4 |
step out |
調試步出當前標記 |
| F5 |
run |
調試運行 |
| F6 |
quit debugging |
退出偵錯模式 |
| F11 |
get all context |
獲得所有變數內容 |
| F12 |
get property of cursor |
獲得當前游標變數 |
三、跟蹤分析
1、代碼覆蓋分析
Xdebug 2.2開始支援對代碼覆蓋的分析,也就是通過對代碼的覆蓋分析,我們可以瞭解到在IDE訪問期間,有哪些程式碼數被執行了,有助於對核心代碼和單元測試有針對性的瞭解和分析,最終提高代碼的品質。
A、涉及的配置
xdebug.coverage_enable=1
//該配置預設為1,也就是預設開啟,如果設定為0,代碼的覆蓋分析就不會進行。
B、涉及的函數
boolean xdebug_code_coverage_started()
//該函數返回布爾值,用來判斷代碼覆蓋分析功能是否開啟,未開啟則返回false。
void xdebug_start_code_coverage( [int options] )
//該函數沒有任何返回,它的作用是開始搜集分析結果集資料,資料是以二維數組形勢//存在,一維參數為分析的檔案名稱字,二維參數為對應的分析行數;另外,在分析檔案
//的每行代碼時,都會產生一個結果碼,如下:
//1:代表代碼已經執行;
//-1:代表代碼未被執行,對應函數參數XDEBUG_CC_UNUSED傳入;
//-2:代表沒有可執行檔代碼存在,對應XDEBUG_CC_DEAD_CODE和XDEBUG_CC_UNUSED
NOTE:
XDEBUG_CC_UNUSED:用來計算分析時包含搜集未被執行的代碼;
XDEBUG_CC_DEAD_CODE:用來計算分析時程式碼是否被執行;
形式如下:
xdebug_start_code_coverage(XDEBUG_CC_UNUSED|XDEBUG_CC_DEAD_CODE);
array xdebug_get_code_coverage()
//該函數返回數組值,用來搜集和傳回碼覆蓋分析的結果集資訊。
void xdebug_stop_code_coverage( [int cleanup=true] )
//該函數不返回任何值,用來停止覆蓋分析,如果傳入參數為true,那麼就會停止分析並清空記憶體中的分析結果集,否者傳入false,反之,還可使用//xdebug_start_code_coverage找回該記憶體資訊。
C、樣本的驗證
Php代碼:
<?php
echo '覆蓋分析進行中...</br>';
// 構建封裝對象
class XdebugCoverageAnalysisModel {
private $_coverage_info;
private $_status;
function __construct() {
$this->_coverage_info = xdebug_get_code_coverage();
$this->_status =xdebug_code_coverage_started();
}
// 擷取分析結果
public functiongetCodeCoverageResult() {
returnjson_encode(xdebug_get_code_coverage());
}
// 開啟覆蓋分析
public functionxdebugStartCodeCoverage() {
xdebug_start_code_coverage( -1 | -2 );
}
// 分析是否執行
public functionxdebugCodeStarted() {
return xdebug_code_coverage_started();
}
}
// 初始化
$apiModel = new XdebugCoverageAnalysisModel();
echo '開啟覆蓋分析...</br>';
$apiModel->xdebugStartCodeCoverage();
// 定義一個測試函數
function coverageSample($a,$b) {
echo '函數結果:'.($a * $b).'</br>';
}
echo '判斷是否開啟...</br>';
$status = $apiModel->xdebugCodeStarted();
if($status=='1') {
echo '開啟覆蓋分析已完成</br>';
} else {
echo '開啟覆蓋分析失敗了</br>';
}
echo '測試函數開啟...</br>';
coverageSample(10,10);
echo '擷取分析結果...</br>';
$result = $apiModel->getCodeCoverageResult();
echo $result.'</br>';
echo '關閉分析開關...</br>';
xdebug_stop_code_coverage();
$status = $apiModel->xdebugCodeStarted();
if($status=='1') {
echo '覆蓋分析已經完成</br>';
} else {
echo '覆蓋分析已經關閉。</br>';
}
unset($result);
unset($apiModel);
?>
瀏覽器結果:
2、PHP指令碼分析
Xdebug的PHP指令碼分析功能比較實用,它可以協助我們分析代碼的瓶頸和影響效能緩慢的問題,為最佳化代碼提供可行性的參考。
A、涉及的配置
xdebug.profiler_enable
//該配置預設為0,為開啟,設定為非0之後,即開啟profiler功能
xdebug.profiler_output_dir
//該配置為上面開啟之後,存放產生分析檔案的位置,需要保證位置可寫入,預設/tmp
xdebug.profiler_enable_trigger
//如果開啟該選項,則在每次請求中如果GET/POST或cookie中包含//XDEBUG_PROFILE變數名,則才會產生效能報告檔案(前提是必須關閉
//xdebug.profiler_enable選項,否則該選項不起作用)。
xdebug.profiler_output_name
//可以使用該配置修改產生的分析檔案,預設cachegrind.out.%p
NOTE:
建議使用xdebug.profiler_enable_trigger替代xdebug.profiler_enable。
B、涉及的函數
string xdebug_get_profiler_filename()
//傳回型別為字串,用來返回分析的檔案名稱字
C、樣本的驗證
當我們開啟分析開關之後,當有指令碼運行就會在指定的位置產生格式為cachegrind.out.xxx的分析檔案:
該檔案的內容不是很直觀,所以需要使用可視化的工具來查看和分析,而Xdebug本身就支援使用第三方的可視化profiler檔案的內容。在Linux下,可以使用KCacheGrind,而在Windows平台,可以使用QCacheGrind,當然還有一些線上的由愛好者開發的工具,例如:WebGrind,具體怎樣使用這些工具,可以參考:
https://xdebug.org/docs/profiler
下面羅列下,WebGrind的效果:
WebGrind可以在這裡下載:
https://github.com/jokkedk/webgrind
四、注意事項
1、避免生產環境開啟profiler和trace,只需開啟遠端偵錯;
2、盡量使用xdebug.profiler_enable_trigger替代xdebug.profiler_enable;
3、如果使用webgrind分析profiler,建議不要放入生產環境,因為其沒有安全限制,任何人都可以訪問;
4、Xdebug的功能雖然強大,但是要均衡效能開銷;
五、遇到問題
問題:Error("DbgProtocol instance has no attribute 'stop'",)
產生該問題的原因大致如下:
A、設定檔配置不正確;
B、.vimrc和php.ini中的port不相同;
C、.vimrc和php.ini中的port與現有的port衝突;
解決:
對照上面的幾條仔細查看配置即可。
NOTE:
有部落格說因為未在URL後添加XDEBUG_SESSION_START=1,其實不然。
技術討論群:489451956(新)