Xdebug 遠程調試,你會用嗎?

前言

在開發過程中,我們最少不了的就是調試,因爲 php 不能像 Java 和 C# 那樣與生俱來的優勢,擁有開箱即用的斷點調試,很多時候我們的開發者都是使用的 var_dump 方法來對結果進行輸出,而有的時候需要查看調用棧時,有的開發者甚至都不知道如和下手。(可以 throw 異常 或者 使用 debug_print_backtracedebug_backtrace 來打印調用棧),雖然很多開發者知道xdebug 但是也會因爲其繁瑣的安裝望而卻步,又或許你在本地高高興興搭建好了,有時候要調試一下外網的,比如測試服務器,你會發現這是個坑,很多文章都沒有正確的引導你去如何的安裝它。

服務器如何安裝 Xdebug

環境準備

  • ubuntu 16.04
  • php 7+
  • XShell

首先打開 Xdebug 官網

是不是看到碩大的 Download 鏈接吸引到了你,如果你知道你的 php 是什麼版本 你可以在這裏愉快的下載,然後並安裝。

偶,我湊,怎麼全是 Windows 的,Linux 的呢?Linux 當然是要從源碼構建啦。

我湊,不會?沒關係咱們一起來學一學,首先新建一個 php 文件,如果你是用包管理器安裝的那麼請直接跳轉到包管理器

// info.php
<?php
phpinfo();

然後放到你的 web 目錄,看清楚,一定是 web 目錄。不要覺得你耍小聰明,使用 php -S 來啓動一個臨時的 web 服務器,不允許,因爲你這樣用到的 php.inicli 的,而不是 fpm 的,當 phpinfo 信息顯示出來。

然後我們回到官網,點擊下載頁面的 custom installation instructions.

來到這個頁面後看到一個輸入框,但是什麼意思呢?

duang,翻譯一下。

這一下明白了吧,就是把 phpinfo 的完整輸出複製到這個框框裏面,然後提交,這下我們回到 phpinfo 頁面, Ctrl + A , Ctrl + C ,一氣呵成,過來粘貼提交。

是的,沒錯,每一步該幹什麼它全都告訴你了,你只需要根據上面提供的 Ctrl+Insert(複製) ,Shift + Insert (粘貼),執行就完事兒。

第 9 步 直接用 vim 打開 php.ini 在最後加入那一行即可。

現在 ,在命令行執行

php -m

看到最後面有 XDebug ,彆着急,這才成功了一半。
當然,到這裏我還要告訴你一個不好的消息,哈哈。
如果你的 php 不是手動編譯的,而是通過 包管理器(apt),因爲 ubuntu 16.04默認的安裝源 安裝的是7.0 ,沒有更高級的版本,你需要用 PPA 源來下載最新的 php 。當然,這裏我們就不在討論了。

包管理器

如果你是使用的 apt 或者 apt-get 安裝的,那麼你可以通過 apt search xdebug 命令來查找 apt 中有關 xdebug 的包。

你可能會看到這個東西,沒錯,直接複製名字執行。

apt install php-xdebug

然後這時候,你去執行 php -m 就會發現 Xdebug 已經安裝好了。

寶塔面板

如果你是寶塔面板的用戶,你可以在面板的軟件管理,對你需要操作的php版本中可以找到有直接安裝 xdebug 擴展的位置。

接下來

不管你是包管理器 還是 手動編譯 安裝的,這裏的內容都需要看了。

打開 fpm 的 php.ini ,如果你是 寶塔面板 用戶,你可以在寶塔的在線編輯,也可以根據 phpinfo 中的 路徑直接編輯, 在 php.ini 最後面加入。

; 這個是節點名字 無所謂大小寫
[XDebug]
; 允許遠程 可以爲 On 或者 1 都表示啓用 , Off 和 0 表示關閉關閉
xdebug.remote_enable = 1
; 遠程主機的 IP 這裏我們填寫,固定的 127.0.0.1 
xdebug.remote_host = 127.0.0.1
; 調試連接端口 請記住這個端口,後續會用到。此配置項默認值爲 9000 ,但是通常 9000 端口被 fpm 佔據 ,故更換端口。
; 另外,請在你服務器的控制面板和服務器防火牆中開放這個端口的進出站。
; 如果你是寶塔面板用戶 請放行此端口。
xdebug.remote_port = 19000
; 接下來的值都是可選的,但是我推薦你使用
; 連接 IDE 的 Key,請記住他,可以自己自定義,主要用來過濾請求。
xdebug.idekey=PHPSTORM
; 這個表示擴展的位置,如果你是編譯安裝的,那麼這個值你應該在第九步已經設置好了,如果你是 使用 包管理器安裝的,那麼這個值應該是自動設置的,而且你不會在這個 php.ini 中找到他,但是此時你已經不用設置它了。
; 如果你是寶塔的用戶,你會發現在你編輯這個文件之前,寶塔已經幫你設置好了
; 另外,通常我建議你將路徑使用引號包裹起來,因爲當路徑中有特殊字符或者空格時會出現問題

; zend_extension=php_xdebug.dll

好了,保存完成後,我們需要重啓 fpm

service php7.0-fpm restart

因爲我的 php 版本是 7.0 所以上面的命令是這樣,如果你的不是,請根據實際情況來定。
如果你是寶塔面板的用戶,請直接在面板操作。
如果你是自己編譯的改了服務名字,不記得了,請執行

service --status-all

這將會打印出所有的服務(有可能會很慢),你可以在其中慢慢找。

當你準備好了之後,我們回到我們的開發端,打開 PHP Storm

客戶端

使用 PHP Storm 打開你的項目。

看到右上角的調試面板,然後選擇這個按鈕,然後進去添加。

請根據圖片提示

emm,過濾請求那個框一時找不到,就描述一下吧,當我們有開啓多個 PHP Storm 窗口時,如果有一個以上的 窗口都啓用的 Xdebug ,那麼,IDE 此時將會不知道該調用哪一個而發生矛盾,你可以在彈出的窗口中選擇使用哪一個項目。

還有,當你通過 APP 請求時,你可能也不需要去過濾,故也不需要去勾選它,使用更加寬鬆的調試。

剛剛圖上既然說到的了 mappings ,但是我一般都不會去啓用它,希望你也用不到。

不知道呢是否還記得,剛剛在修改 php.ini 時,我讓你記住的那個 IDE Key,現在你可以用到它了。

接下來,我們還要去修改另外一個 配置,本地的調試端口。

按下 Ctrl+Alt+S 打開設置界面,或者在 左上角 File > Settings 並且定位到

Languages & Frameworks > PHP > Debug

當你設置好這個端口後,請記住它,接下來就會用到。

偶,好像最後一個標註錯誤,最後一個是,當在項目外時,在第一行斷點。

這個纔是在首行進行斷點。

設置到這裏,你是不是覺得應該OK了?當然,不是,是否記得剛剛在 準備工具 中提到的 Xshell 和 在 php.ini 中設置的 端口沒有使用。

Xshell 設置

請確保在你的 Xshell 左側的 會話管理器 中已經添加了你的服務器連接。

圖片中雖然已經對大部分內容進行了模糊處理,畢竟是外網服務器,如有遺漏之處,也請不要對其進行惡意請求,謝謝。

點開屬性,依次選擇 連接 >SSH>隧道 > 添加

請參考圖片進行操作

如果隧道轉發沒有成功該怎麼辦?

  • 查看本地端口的使用是否正確。

打開命令行,執行如下命令,其中 9001 是在 PHP Storm 中設置的端口。

# 找到 PID
netstat -aon | findstr 9001
# 通過 PID 找到 是誰在使用。
tasklist | findstr {PID}
# 結束進程 如果這端口被佔用 可以使用如下命令結束,當然,我更加推薦你換個端口。
taskkill /PID {PID}

如果本地正常,那麼問題就應該在服務器。

在服務端執行如下命令,19000 爲 服務器設置的端口。

lsof -i:19000

此時,如果隧道未連接,那麼這個端口是不應該被佔用的,反之則顯示爲一個 SSHD,如果不爲空,那麼就是端口被其他程序佔用了,我建議你換個端口。

最後一線

當以上步驟都完成後,我們就可以來進行測試了嗎?不是的,還有一步,代碼同步 ,這是非常重要的一步。

代碼同步

顧名思義,代碼同步,需要你本地的代碼和線上的代碼一致。爲了在調試時追蹤跳轉文件,避免因文件無法映射而導致無法同步。

一般情況下,我們都是使用 git 來進行代碼託管,直接從 git 上拉取代碼即可,這樣就能確保我們的代碼是同步的,現在我們就可以 happy 的進行調試代碼了,但是當你直接訪問你卻發現,IDE 並沒有攔截你的請求,是不是很尷尬。

啓用調試

如圖上所說,其實這種情況下我們也可以正常進行調試。

當我們直接訪問,卻發現 PHP Storm 並沒有捕獲到我們的請求這是爲什麼?

原因很簡單,我們沒有告訴 Xdebug 我們要關心這個請求,否則試想一下,有幾個人同時請求你的網頁,全部被 IDE 接收了,是不是瘋了?

這時候,我們只需要在 URL 後面加上 XDEBUG_SESSION_START=233 首先 ,這個 XDEBUG_SESSION_START 是必須的,但是他的值是可以隨便填寫的。
此時 URL 變成了,參考文檔

https://xxx.com?XDEBUG_SESSION_START=233

就可以正常捕獲了。

如果你覺得手動添加,很麻煩,那你還可以安裝一個 Chrome 插件。

Xdebug helper - Chrome 網上應用店

這個工具會自動幫你設置,只不過他是在 cookie 裏面設置,依賴cookie。

安裝完成後,需要先配置,右鍵擴展欄的蟲子圖標,選擇選項

選擇 PHP Storm, 當然,別忘了旁邊的 Save

常見問題

無法斷點

  • 確認服務器端口在隧道連通後,是 SSHD 在使用那一個端口。
  • 確認服務器端口在防火牆以及服務器面板放行了端口。
  • 確認本地端口是被 phpstorm 所使用的。
  • 確認 XShell 隧道連接是成功狀態。
  • 確認 PHP Storm 中的 電話 圖標是綠色,並且正確配置了調試服務器。

本地無法跳轉

這個主要是表現在 使用追蹤時,突然就跳出了循環,明明下面還有斷點,這是因爲一些項目中使用了 自定義一些複雜的表達式來引入文件,導致沒法映射導致,比如 微擎 。這時候就需要單步驟調試,到出錯的位置,Xdebug 的 Debugger 窗格會爲我們提示。

手動添加映射

手動添加映射

也可以直接在上級目錄,爲整個目錄添加映射。

映射添加完成後,就可以以繼續調試了

但是要注意路徑對應否則會影響調試。

調試自動斷開 nginx 返回 504

這是應爲,你沒有調整 PHP 和 FPM 以及 Nginx 的最大執行時間,修改到一個較大的值即可。

寶塔面板問題

寶塔面板的用戶你會發現你網頁端使用的 php 版本和 cli 的版本不一致,可以打開

網站 > PHP 命令行版本(就在添加網站那一排的最後一個按鈕)

然後再進入

軟件商店 > 對應的 php 版本 > 設置 > 安裝擴展 > 選擇 Xdebug

順便還可以把超時這些也在這裏修改了 解決上面的 504 問題

當安裝完 Xdebug 後,切換到 服務 然後選擇 「重啓」 一定是 重啓 而不是 重載配置

然後點擊下面的 > phpinfo > 查看 phpinfo 。這時候你就能看到了,然後可以搜索 xdebug 驗證是否安裝成功。

接着 去修改 php.ini ,配置我們方纔 提到的

注意

  • 不能用於 Swoole
  • 不能用於 Workerman
  • 理論上類似框架都不能,不過實踐出真理
  • 理論上只能同時一臺物理機對應一臺服務器進行調試,因爲 xshell 隧道佔用。當然 你可以多啓動 fpm 使用不同的 php.ini 文件(理論可行)。

使用 Xdebug

圖例:

  • 1、Debug 窗口 在啓動 debug 時 該窗口會自動打開
  • 2、跳轉到下一個斷點
  • 3、暫停執行
  • 4、結束腳本執行
  • 5、查看所有斷點
  • 6、屏蔽所有斷點
  • 7、逐行執行代碼
  • 8、進入方法或文件
  • 9、強制進入方法或文件
  • 10、跳出方法或文件
  • 10和11中間 ,運行到光標所在行,如果期間有斷點會優先執行斷點
  • 11、執行表達式
  • 12、Debugger 窗體,可以查看執行的調用棧,查看/修改運行時環境,變量。
  • 13、Console 窗體,可以執行命令
  • 14、腳本結果窗體

這些都是有快捷鍵的,可以把鼠標放上去看,可以參考官方手冊

結束

曾經因爲在遠程調試走了很多彎路,至此就專門去研究這個,經過多次的實踐和應用,穩定了次方案進行安裝,故發出來,也希望對你有所幫助。

當你習慣了使用 Xdebug 調試,或許你以後都不再想用 var_dump 了。

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章