為什麼需要Debugger?
很多PHP程式員調試使用echo、print_r()、var_dump()、printf()等,其實對于有較豐富開發經驗的程式員來說這些也已經足夠了,他們往往可以在程式執行的過程中,通過輸出特定變量的值可以判斷程式執行是否正确,甚至效率高低也可以看出來(當然可能還需要使用一些時間函數)。那麼我們為什麼還需要一個專門的調試程式來監控我們的程式運作呢? 這個問題的答案不妨留到後面來揭曉。
什麼是Xdebug?
官方站點:www.Xdebug.org
如何安裝Xdebug?
以PHP5.1.4,Windows平台為例(其它PHP版本,其它平台請參看官網文檔):
2. 将下載下傳的php_xdebug-5.1.2-2.0.0beta6.dll放到C:/php5/ext目錄,重命名為php_xdebug.dll;
3. 編輯php.ini,加入下面幾行:
extension=php_xdebug.dll
[Xdebug]
xdebug.profiler_enable=on
xdebug.trace_output_dir="I:/Projects/xdebug"
xdebug.profiler_output_dir="I:/Projects/xdebug"
後面的目錄“I:/Projects/xdebug”為你想要放置Xdebug輸出的資料檔案的目錄,可自由設定。
4. 重新開機Apache;
5. 寫一個test.php,内容為<?php phpinfo(); ?>,如果輸出的内容中有看到xdebug,說明安裝配置成功。
現在我們就可以開始使用Xdebug強大的功能了!
<a href="http://blog.csdn.net/Haohappy2004/archive/2006/07/08/893060.aspx"> 使用Xdebug調試和優化PHP程式[2]</a>
作者:Haohappy
MSN: haohappy at msn.com
2006-07-04
Go on..現在我們來從最簡單的程式調試開始一步步介紹Xdebug。
調試:
我們先寫一個可以導緻執行出錯的程式,例如嘗試包含一個不存在的檔案。
testXdebug.php
<?php
require_once(‘abc.php’);
?>
然後通過浏覽器通路,我們驚奇地發現,出錯資訊變成了彩色的了:
不過除了樣式改變,和我們平時列印的出錯資訊内容沒什麼不同,意義不大。好,我們繼續改寫程式:
testXdebug2.php
testXdebug();
function testXdebug() {
require_once('abc.php');
}
輸出資訊:
發現了什麼? Xdebug跟蹤代碼的執行,找到了出錯的函數testXdebug()。
我們把代碼再寫得複雜一些:
testXdebug3.php
requireFile();
function requireFile() {
呵呵,也就是說Xdebug具有類似于Java的Exception的“跟蹤回溯”的功能,可以根據程式的執行一步步跟蹤到出錯的具體位置,哪怕程式中的調用很複雜,我們也可以通過這個功能來理清代碼關系,迅速定位,快速排錯。
<a href="http://blog.csdn.net/Haohappy2004/archive/2006/07/17/932581.aspx"> 使用Xdebug調試和優化PHP程式[3]</a>
其實PHP函數debug_backtrace()也有類似的功能,但是要注意debug_backtrace()函數隻在PHP4.3.0之後版本及
PHP5中才生效。這個函數是PHP開發團隊在PHP5中新增的函數,然後又反向移植到PHP4.3中。
如何利用Xdebug使調試資訊更加美觀?
Xdebug擴充加載後,Xdebug會對原有的某些PHP函數進行覆寫,以便好更好地進行Debug。比如var_dump()函數,我們知道通常我們需要在函數前後加上”<pre>…</pre>”才能夠讓輸出的變量資訊比較美觀、可讀性好。但是加載了Xdebug後,我們不再需要這樣做了,Xdebug不但自動給我們加上了<pre>标簽,還給變量加上顔色。
例:
$arrTest=array(
"test"=>"abc",
"test2"=>"abc2"
);
var_dump($arrTest);
輸出:
看到了嗎? 數組元素的值自動顯示顔色。
如何利用Xdebug測試腳本執行時間
測試某段腳本的執行時間,通常我們都需要用到microtime()函數來确定目前時間。例如PHP手冊上的例子:
<code><?php</code>
<code>/**</code>
<code>* Simple function to replicate PHP 5 behaviour</code>
<code>*/</code>
<code>function </code><code>microtime</code><code>_float</code><code>()</code>
<code>{</code>
<code> list(</code><code>$usec</code><code>, </code><code>$sec</code><code>) = </code><code>explode</code><code>(</code><code>" "</code><code>, </code><code>microtime</code><code>());</code>
<code>return ((float)</code><code>$usec </code><code>+ (float)</code><code>$sec</code><code>);</code>
<code>}</code>
<code>$time_start </code><code>= </code><code>microtime</code><code>_float</code><code>();</code>
<code>// Sleep for a while</code>
<code>usleep</code><code>(</code><code>100</code><code>);</code>
<code>$time_end </code><code>= </code><code>microtime</code><code>_float</code><code>();</code>
<code>$time </code><code>= </code><code>$time_end </code><code>- </code><code>$time_start</code><code>;</code>
<code>echo </code><code>"Did nothing in $time seconds</code><code>/n</code><code>"</code><code>;</code>
<code>?></code>
<code></code>
<code>但是</code><code>microtime()</code>傳回的值是微秒數及絕對時間戳(例如“0.03520000 1153122275”),沒有可讀性。是以如上程式,我們需要另外寫一個函數microtime_<code>float()</code><code>,來将兩者相加。</code>
<code>Xdebug</code><code>自帶了一個函數</code><code>xdebug_time_index()</code><code>來顯示時間。</code>
如何測定腳本占用的記憶體?
有時候我們想知道程式執行到某個特定階段時到底占用了多大記憶體,為此PHP提供了函數memory_get_usage()。這個函數隻有當PHP編譯時使用了--enable-memory-limit參數時才有效。
Xdebug同樣提供了一個函數xdebug_memory_usage()來實作這樣的功能,另外xdebug還提供了一個xdebug_peak_memory_usage()函數來檢視記憶體占用的峰值。
如何檢測代碼中的不足?
有時候代碼沒有明顯的編寫錯誤,沒有顯示任何錯誤資訊(如error、warning、notice等),但是這不表明代碼就是正确無誤的。有時候可能某段代碼執行時間過長,占用記憶體過多以緻于影響整個系統的效率,我們沒有辦法直接看出來是哪部份代碼出了問題。這時候我們希望把代碼的每個階段的運作情況都監控起來,寫到日志檔案中去,運作一段時間後再進行分析,找到問題所在。
回憶一下,之前我們編輯php.ini檔案
加入
這幾行,目的就在于把執行情況的分析檔案寫入到”I:/Projects/xdebug”目錄中去(你可以替換成任何你想設定的目錄)。如果你執行某段程式後,再打開相應的目錄,可以發現生成了一堆檔案,例如cachegrind.out.1169585776這種格式命名的檔案。這些就是Xdebug生成的分析檔案。用編輯器打開你可以看到很多程式運作的相關細節資訊,不過很顯然這樣看太累了,我們需要用圖形化的軟體來檢視。
哇,非常漂亮,我們很直覺地看到index.php中我們調用了一個函數testXdebug(),testXdebug()中又調用了requireFile()函數。這樣我們就可以非常友善地檢視整個腳本的程式結構。
另外,我們還可以看到每個函數被調用的次數及執行所花費的時間!這對于測試程式性能非常有用。
好了,這麼一個簡單的程式不太能顯示出Xdebug+WinCacheGrind的強大,我給出一個稍大點的例子(一個基于Zend Framework的CMS的index.php):
從上圖可以看到:整個程式的結構,每個函數被調用的次數,執行時間都一目了然。
小結:
Xdebug提供了各種自帶的函數,并對已有的某些PHP函數進行覆寫,可以友善地用于調試排錯;Xdebug還可以跟蹤程式的運作,通過對日志檔案的分析,我們可以迅速找到程式運作的瓶頸所在,提高程式效率,進而提高整個系統的性能。