跨平台PHP调试器设计及使用方法——使用
? ? ? ? 經(jīng)過之前六篇博文的分析和介紹,大家應(yīng)該對這套調(diào)試器有個(gè)初步的認(rèn)識(shí)。本文我將講解它的使用方法。(轉(zhuǎn)載請指明出于breaksoftware的csdn博客)
? ? ? ? 上圖是該軟件界面的布局,我們之后的講解也將圍繞著這些功能展開。
文件夾管理
? ? ? ? 在查看一個(gè)功能代碼前,我們往往需要知道其邏輯所在的路徑。文件夾管理功能就是提供給用戶設(shè)置代碼邏輯路徑的地方。用戶可以在這個(gè)功能里管理需要調(diào)試的代碼工程路徑。
新增目錄
? ? ? ? 點(diǎn)擊文件夾區(qū)域第二個(gè)按鈕,彈出一個(gè)對話框,我們可以在輸入框中輸入一個(gè)目錄,然后點(diǎn)擊Save。這樣新目錄就加進(jìn)來了。
刪除目錄
? ? ? ? 首先選擇一個(gè)根文件夾,然后點(diǎn)擊文件夾區(qū)域第三個(gè)按鈕,這樣就在調(diào)試器中刪除了該目錄的查看。
? ? ? ? 這塊的邏輯見phpdebugserver.py的request_files_tree函數(shù)。ide_config.py文件是實(shí)現(xiàn)路徑增刪讀的實(shí)現(xiàn)模塊,它直接操作的是ide.cfg文件中folders區(qū)域。
查看代碼
? ? ? ? 作為一個(gè)可視化的調(diào)試器,查看被調(diào)試源碼是基礎(chǔ)功能。我們可以通過單擊文件夾管理區(qū)域中文件名來展現(xiàn)文件內(nèi)容。
調(diào)試開關(guān)
? ? ? ? 調(diào)試開關(guān)是一個(gè)非常必要的設(shè)置。我們在一臺(tái)機(jī)器上搭建了調(diào)試服務(wù)后,并不是每次請求都是要調(diào)試的。在需要調(diào)試的時(shí)候,我們可以開啟這個(gè)開關(guān)。這個(gè)時(shí)候調(diào)試器的狀態(tài)機(jī)根據(jù)是否設(shè)置了斷點(diǎn)來決定調(diào)試的方式。
? ? ? ? 如果設(shè)置了斷點(diǎn),則進(jìn)入調(diào)試狀態(tài)后一直運(yùn)行,直到遇到斷點(diǎn)而中斷。比如我們在2,3,4行設(shè)置了斷點(diǎn),啟動(dòng)調(diào)試后,程序會(huì)中斷在第3行
? ? ? ? 如果沒有斷點(diǎn),則中斷到第一行代碼。
? ? ? ? 當(dāng)調(diào)試開關(guān)關(guān)閉時(shí),調(diào)試功能鍵全部沒禁用。
? ? ? ??反之則全部被啟用。
調(diào)用堆棧
? ? ? ? 調(diào)用堆棧可以幫助我們回溯函數(shù)的調(diào)用過程。比如某一個(gè)函數(shù)在代碼中多個(gè)地方被調(diào)用,而本次調(diào)試時(shí)它的內(nèi)部正好出錯(cuò),可能是入?yún)㈠e(cuò)誤,這個(gè)時(shí)候我就需要回溯下調(diào)用堆棧,看看哪個(gè)地方調(diào)用此函數(shù)出錯(cuò)的。下圖是我們調(diào)用到checkNum函數(shù)時(shí)的調(diào)用堆棧信息,它顯示在綜合信息區(qū)域
變量
? ? ? ? 變量查看是我們在調(diào)試過程中經(jīng)常使用到的功能。當(dāng)我們邏輯中斷在某一行代碼時(shí),我們可以通過綜合信息區(qū)域的變量窗口查看相關(guān)變量。默認(rèn)的,我只是顯示了當(dāng)前堆棧上的變量和全局變量,比如下面一段邏輯
dd();function checkNum($number)
{if($number>1){throw new Exception("Value must be 1 or below");}return true;
}function dd() {try{checkNum(2);//If the exception is thrown, this text will not be shownecho 'If you see this, the number is 1 or below';}catch(Exception $e){echo 'Message: ' .$e->getMessage();}
}
? ? ? ? 當(dāng)我們調(diào)用到異常拋出行時(shí),我們此時(shí)的堆棧上只有一個(gè)臨時(shí)變量
? ? ? ? 但是此時(shí),該函數(shù)外層還有兩個(gè)調(diào)用堆棧,而這兩個(gè)調(diào)用堆棧(見“調(diào)用堆棧”節(jié)中的圖)上的參數(shù)是默認(rèn)不顯示的。因?yàn)樗臄?shù)據(jù)量可能比較大,而且可能沒太多必要,所以我默認(rèn)把它關(guān)閉了。當(dāng)然我也提供的開啟全棧數(shù)據(jù)的開關(guān)。用戶可以在Tools的Setting中開啟All Stack Parameters功能
?
斷點(diǎn)
? ? ? ? 斷點(diǎn)也是調(diào)試器非常基礎(chǔ)的功能,我支持了除了watch類型之外的所有其他斷點(diǎn)形式。
? ? 行斷點(diǎn)
? ? ? ? 新增行斷點(diǎn)有三種方式。一種是在代碼區(qū)域的行號(hào)上點(diǎn)擊一下
?
? ? ? ? 還有一種方式是在綜合功能區(qū)域Breakpoint的Tab中點(diǎn)擊“新增斷點(diǎn)”按鈕
? ? ? ? 還有一種是在行號(hào)上右擊,然后選擇“Add Line Breakpoint”。該操作還是會(huì)彈出上面這個(gè)窗口設(shè)置斷點(diǎn)信息。
?
? ? ? ? 我們可以通過綜合信息區(qū)域的Breakpoint頁面查看斷點(diǎn)信息
?
? ? ? ? 刪除斷點(diǎn)操作也非常簡單。我們可以在已設(shè)置斷點(diǎn)的行號(hào)上點(diǎn)擊一下,或者在綜合信息區(qū)域的Breakpoint頁對斷點(diǎn)執(zhí)行delete操作。
? ? 函數(shù)調(diào)用斷點(diǎn)
? ? ? ? 當(dāng)我們需要調(diào)試某函數(shù)時(shí),我們可以設(shè)置函數(shù)調(diào)用斷點(diǎn)。這樣一旦函數(shù)被調(diào)用到,就會(huì)被中斷到函數(shù)最開始執(zhí)行處。我們可以通過新增斷點(diǎn)窗口對dd這個(gè)函數(shù)設(shè)置函數(shù)調(diào)用斷點(diǎn)。
? ? ? ? 我們在第7行調(diào)用了dd,最終程序斷在dd函數(shù)執(zhí)行的第一行,即21行。
? ? 函數(shù)返回?cái)帱c(diǎn)
? ? ? ? 顧名思義,函數(shù)返回?cái)帱c(diǎn)是斷在指定函數(shù)的返回處。我們還以dd這個(gè)函數(shù)為例。
? ? ? ? 當(dāng)這個(gè)斷點(diǎn)被命中后,此時(shí)調(diào)試器尚不處在代碼中,我們可通過調(diào)用堆棧看到
? ? ? ? 此時(shí),我們需要執(zhí)行一下step over讓調(diào)試器進(jìn)入代碼中。從下圖可見,綠標(biāo)的那行就是執(zhí)行完dd函數(shù)后應(yīng)該要被執(zhí)行的代碼。
? ? 異常斷點(diǎn)
? ? ? ? 異常斷點(diǎn)是用于幫助我們在異常發(fā)生前中斷的斷點(diǎn)。比如我們程序中使用異常方式終止流程執(zhí)行,則可能在代碼很多地方遍布異常拋出邏輯。而本次調(diào)試時(shí)最終在何處拋出異常,則比較難以定位。這個(gè)時(shí)候異常斷點(diǎn)就是一個(gè)非常好的方案。我們以拋出Exception類型異常為例,首先我們要在斷點(diǎn)設(shè)置窗口中設(shè)置斷點(diǎn)信息
? ? ? ? 然后觸發(fā)調(diào)試,可以發(fā)現(xiàn)流程中斷在拋出異常的地方。此時(shí)我們便可以分析上下文和變量信息查看異常的原因。
? ? 條件斷點(diǎn)
? ? ? ? 條件斷點(diǎn)也是可以幫我們解決繁瑣問題的一個(gè)方案。比如我們在一個(gè)循環(huán)中調(diào)用一個(gè)函數(shù),我們希望這個(gè)函數(shù)在循環(huán)中被調(diào)用67次時(shí)被中斷。那么如果我們在函數(shù)上下斷點(diǎn),則可能之前66次中斷是沒用的,還要不停的在中斷后點(diǎn)擊Run。這個(gè)過程實(shí)在太繁瑣。條件斷點(diǎn)就可以幫我們解決這個(gè)問題。我們只要在中斷所在行設(shè)置條件,比如設(shè)置迭代索引為67時(shí)中斷。下面例子我們以迭代索引為6為例
? ? ? ? 觸發(fā)調(diào)試后,我們可以發(fā)現(xiàn)中斷在第32行。而且通過變量查看器,我們可以發(fā)現(xiàn)此時(shí)$i的值為6。
變量修改
? ? ? ? 變量修改功能是調(diào)試時(shí)人為修改變量值從而影響邏輯執(zhí)行流程的功能。比如上例介紹異常斷點(diǎn)時(shí),我們判斷$number是否大于1,如果大于則拋出異常。如果我們在調(diào)試時(shí)不想此時(shí)拋出異常,則可以修改$number的值。首先我們在第11行下斷點(diǎn),并觸發(fā)調(diào)試。我們查看下此時(shí)變量的值
? ? ? ? 我們右擊變量查看器中$number的值,彈出下面的窗口
? ? ? ? 我們修改$number的值為1
? ? ? ? 點(diǎn)擊保存,我們在查看變量查看器,并執(zhí)行一次step over。可以看到$number已經(jīng)變成1,而且之后也沒走拋出異常的邏輯。
變量前后對比功能
? ? ? ? 這個(gè)功能也是默認(rèn)關(guān)閉的。因?yàn)樗枰4嬷袛嗲昂髢刹降娜珬W兞?#xff0c;這個(gè)操作非常耗時(shí)。我們可以通過Tools的Setting中的Variables Watch開關(guān)開啟此功能。我們還需要開啟All Stack Parameters功能。
? ? ? ? 我們在第4行下斷點(diǎn),同時(shí)將$a添加到變量監(jiān)控中
? ? ? ? 點(diǎn)擊綜合信息區(qū)的Variables Watch頁,并觸發(fā)調(diào)試,此時(shí)$a在調(diào)試前后都沒值
? ? ? ? 執(zhí)行一次step over操作,讓第4行被執(zhí)行
? ? ? ? 此時(shí)$a被修改為123了。左側(cè)區(qū)域是第4行被執(zhí)行之前的值,右側(cè)是第4行被執(zhí)行之后的值。我們繼續(xù)step over兩次。看看之后的變化
?
文件監(jiān)控功能
? ? ? ? 當(dāng)我們調(diào)試一個(gè)功能時(shí),可能還需要查看一些文件變化,比如我們可能需要監(jiān)控一些日志文件。此時(shí)我們可以使用綜合信息區(qū)的Files Watch功能。
? ? ? ? 該文件會(huì)隨著我們調(diào)試進(jìn)行而變化,我們在該Tab頁下也將看到文件變化的過程(手工點(diǎn)擊刷新,也可以做成自動(dòng))。
請求記錄和發(fā)送
? ? ? ? 這個(gè)功能是為了記錄調(diào)試時(shí)請求并模擬該請求而設(shè)計(jì)的。當(dāng)我們從網(wǎng)頁中觸發(fā)一些請求前,我們可能需要填寫一些數(shù)據(jù)。一次調(diào)試后,這些數(shù)據(jù)將不在頁面中存在,而需要重新填寫并提交,這個(gè)過程非常麻煩。我們可以在調(diào)試過程中記錄請求內(nèi)容,并制定請求路徑,從而達(dá)到記錄功能。
? ? ? ? 比如我們發(fā)送http://127.0.0.1/index.php?pamra1=value1¶m2=value2請求,我們在變量查看器中可以看到
?
? ? ? ? 我們點(diǎn)擊請求記錄按鈕,并該該請求命名
? ? ? ? 在主界面右側(cè)的變量記錄區(qū)域我們可以看到它的信息。點(diǎn)擊筆狀編輯按鈕,我們將Url路徑和發(fā)送方式填入
? ? ? ? 點(diǎn)擊保存即可。我們還可以對變量進(jìn)行增刪改,比如我們增加一個(gè)變量param3=value3,則
? ? ? ? 我們讓此次調(diào)試結(jié)束。然后再次打開上面請求編輯界面,點(diǎn)擊Send按鈕。此時(shí)會(huì)新打開一個(gè)頁面發(fā)送請求,然后我們的調(diào)試器中斷后會(huì)在變量區(qū)域顯示新的請求參數(shù)
?
總結(jié)
以上是生活随笔為你收集整理的跨平台PHP调试器设计及使用方法——使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跨平台PHP调试器设计及使用方法——界面
- 下一篇: 跨平台PHP调试器设计及使用方法——拾遗