PHP 調試 - 如何調試 PHP 代碼(包括 Drupal 調試技術!)

已發表: 2019-09-03

調試不是我們開發人員所期待的。 開發人員厭惡錯誤,但為了能夠構建出優質的軟件,調試是開發人員生活中不可或缺的一部分。 每個 PHP 開發人員都有不同的風格和調試代碼的首選方法。 這取決於他們的經驗、解決問題的方法以及最重要的 - 他們手頭的時間!

調試有多重要,為什麼需要調試代碼?

調試是確保質量結果的軟件開發生命週期的一個組成部分。
想像一下 - 代碼庫很大,您是項目的新手,您沒有太多關於項目/功能的細節。 但是你應該修復一個錯誤。 我們從哪裡開始? 我們從逐步分析代碼開始,以了解做了什麼以及哪裡出錯了。 我的朋友們,這就是調試。 調試是一門藝術,可以通過實踐和經驗變得更好。

如何調試你的 PHP 代碼

好的,這是我在開發生涯中遇到的一個案例。 有一個建立在 Wordpress 上的商業網站,其中結帳​​過程大約需要 5-8 分鐘,我被要求解決它。 在這種情況下,我對 Wordpress 的工作原理知之甚少。 所以我開始從列表中一一勾選選項,例如,(a) 是不是因為某個插件? (b) 與主題有關嗎? (c) 是否有任何自定義代碼庫? 等等。

幫助我進行 php 調試和解決此案例的工具是 Blackfire。 這為所有函數的堆棧跟踪提供了一個更具用戶可讀性的選項,即整個過程中每個函數所花費的時間。 通過使用它,我發現了消耗結帳過程的功能。 您只需要進行一些設置即可將密鑰添加到您的代碼庫中,並且您已經準備好使用文檔分析任何功能。
因此,如果您了解多種 php 調試方法,則可以解決這些錯誤。

代碼調試技巧

讓我談談我用於調試 PHP 的一些技術。
檢查您編寫的函數或方法是否被調用的一種簡單且最常見的方法是編寫退出。 沒有任何開發人員沒有使用過它!
要檢查某個變量的值,print_r()、var_dump()、var_export()。 好的,讓我們看看區別。

例子:

 假設一個數組 
$a = array( 1, array( "a", "b") );
打印_r($a);

 
大批
(
[ 0 ] => 1
[ 1 ] =>數組
(
[ 0 ] => 'a'
[ 1 ] => 'b'
)
)

這提供了人類可讀的格式和有關變量的信息。 此外,我們可以使用 print_r($var, true) 將其存儲到變量中。

 var_dump( $a );
 數組( 3 ) {
[ 0 ]=>
整數( 1 )
[ 1 ]=>
  數組( 2 ) {
[ 0 ]=>
字符串( 1 ) "a"
[ 1 ]=>
字符串( 1 ) "b"
}
}

這將打印每個值的類型、長度。 這比 print_r() 更快
var_export( $a );

 數組(
  0 => 1 ,
  1 =>
  數組(
    0 => 'a' ,
    1 => 'b' ,
),
)

這將打印每個值的類型、長度。 這比 print_r() 更快
var_export( $a );

如果變量存在,則返回有效的 php,否則返回 false。 這意味著 var_export 的輸出可以直接在 php 文件中使用。

你有沒有使用過 Drupal 核心提供的debug($var, NULL, TRUE) ? 這根據傳遞給 php 調試函數的參數使用 print_r() 或 var_export。

像下面這樣的警告怎麼樣,你不知道哪一行代碼導致了這樣的警告。

警告:為第485行 /modules/node/node.module 中的 foreach() 提供的參數無效。

我們知道有很多地方會調用node模塊。 那麼,你如何解決這個問題? 一種不使用任何其他外部資源的更快方法是使用 PHP 函數debug_backtrace() 。 轉到“drupal_set_message”,因為你知道,這是打印警告的方法。 把下面的行,在那個函數中

debug_backtrace();

輸出:

大批
(
[ 0 ] =>數組
(
[文件] => /includes/common.inc
[行] => 552
[功能] => drupal_set_message
[參數] =>數組
(
[ 0 ] => 警告:無效

為 foreach() 提供的參數

/modules/node/node.module 在第504
[ 1 ] => 錯誤
)

)

[1] =>數組
(
[文件] => /modules/node/node.module
[行] => 504
[功能] => error_handler
[參數] => 數組
(
[ 0 ] => 2
[ 1 ] => 無效參數
為 foreach() 提供
[ 2 ] => /模塊/節點/
節點模塊
[ 3 ] => 504
[ 4 ] => 數組
(
[參數] =>
[修訂] =>
[重置] =>
...
)

)

)

[2] =>數組
(
[文件] => /sites/all/modules/custom/custom_module
/custom_module.module
[行] => 10
[功能] => node_load
[參數] => 數組
(
[ 0 ] =>
)

)

[3] =>數組
(
[文件] => /includes/form.inc
[行] => 365
[功能] => custom_module_form_alter
[參數] => 數組
(
...

該函數顯示了在導致警告的過程中調用的所有函數的堆棧。 確保限制限制,否則如果堆棧顯示時間過長,PHP 會顯示“內存耗盡”消息。

通過 CLI 調試:

聽說過phpdbg ! 是的,PHP 5.6+ 提供了一個 php 擴展,用於從命令行調試 php 文件。
打開終端,輸入“phpdbg”。 這將啟動一個交互式 php 調試器外殼。 您也可以使用斷點! 試試吧 - 調試 PHP 的隱藏方式。
唯一的問題是:您必須習慣 phpdbg 的命令才能更好地使用它。

通過 Drupal 調試:

Devel Kint: Drupal 開發人員經常使用它。 Kint 是 Devel 模塊的一個子模塊,可用於與 dump() 一起調試 Drupal 8 twig 模板;

數據庫日誌:誰不知道這個 Drupal 模塊?! 在 D7 中它是watchdog(),而 D8 中它是記錄器服務。

\Drupal::logger( 'my_module' )->debug($message);

但是我們不鼓勵使用這個模塊的唯一原因,即使我們喜歡它,也是每次都會將日誌消息寫入數據庫!

並且想像一下,如果它是一個巨大的數據庫,這會更糟並且會影響性能。 這就是原因,不建議在生產站點上使用 DBLOG 模塊。
您是否還想使用 DBLog、模塊並降低性能影響? 也有一個解決方案 - Dlog 過濾器。 這是一個貢獻模塊,有助於限制寫入數據庫的日誌類型。 例如,如果您只想存儲嚴重性為“錯誤”的日誌,則可以使用此模塊對其進行配置。 所以你不必完全擺脫Dblog模塊。 哦,是的,這個模塊是我貢獻的 ;)

網頁分析器

Web profiler 是 Devel 再次提供的一個貢獻模塊。 啟用模塊後,您將在窗口底部看到一個報告。 每當加載頁面時,此報告都會為我們提供頁面加載時間、頁面中運行的查詢數量、表單數量、該頁面中的 js/css 文件數量等。

網絡分析器

是的,這甚至可以通過單擊來提供每個部分的詳細信息。 例如,下圖顯示了主頁中的查詢。

調試

XDebug - 通過 IDE 調試:

如果使用 IDE 進行編碼,大多數人更喜歡的最佳且更用戶友好的調試方式是使用 XDebug。 XDebug 是一個有助於開發和調試的 PHP 擴展,並提供了一個單步調試器,您可以將它與像 PHPStorm 這樣的 IDE 一起使用。 當然,為了獲得最佳結果,您必須付出更多努力來使用您正在使用的 IDE 安裝和配置擴展。