PhpStorm Xdebug遠端除錯環境搭建原理分析及問題排查
http://blog.nsfocus.net/phpstorm-xdebug-remote-debugging-troubleshooting/
對於簡單的工程,直接print_r();exit()已經足夠,但是對於大型專案有時就有點力不從心,如果直接將apache部署在本地,phpstorm除錯原生代碼這種方式也可以,我以前就是這麼幹的,這篇文章主要介紹遠端除錯系問題排除。
1,環境介紹
本地:windows7(192.168..)+phpstorm8
遠端:Ubuntu14.04(192.168.3.206)+apache2+php5
2 遠端環境配置
2.2 xdebug安裝
Ubuntu下直接apt-get安裝,安裝命令如下:
`apt-get install php5-xdebug`
2.3 配置
首先通過locate定位到xdebug.ini,這個位置一定得對,在Ubuntu上位於/etc/php5/apache2/conf.d/20-xdebug.ini
zend_extension=xdebug.so xdebug.idekey=PHPSTORM xdebug.remote_connect_back = 1 ;//如果開啟此,將忽略下面的 xdebug.remote_host 的引數 ;xdebug.remote_host=192.168.x.x ; //注意這裡是,客戶端的ip<即IDE的機器的ip,不是你的web server> xdebug.remote_enable=on xdebug.remote_port = 9001 ;//注意這裡是,客戶端的埠<即IDE的機器的ip,不是你的web server> xdebug.remote_handler = dbgp xdebug.auto_trace = 1 xdebug.remote_log = /tmp/xdebug.log
3 本地phpstorm配置
下面的配置有執行順序要求,請一步一步來。
3.1 下載遠端程式碼
phpstorm在新建專案的時候提供了選項,可以通過ftp/sftp遠端下載程式碼,直接按照提示下一步下一步就可以。
3.2 新增php直譯器
通過file->settings->Languages & Frameworks找到php欄,
3.3 配置Debug
路徑還是在file->settings->Languages & Frameworks->PHP,選擇Debug,選擇要監聽的埠,這裡設定為9001,如圖所示:
設定完埠還需要設定DBGp Proxy,配置如下:
在設定完Debug頁面後,在DBGp Proxy頁面的埠已經確定,新增上IDE key為剛才xdebug配置檔案設定的key:PHPSTORM,Host則為要除錯的遠端主機。
3.4 配置Server
通過通過file->settings->Languages Frameworks->PHP找到Servers,Host對應遠端主機IP,Debugger選用Xdebug,如果是遠端除錯,一定得開啟路徑對映功能,否則無法除錯,本地的路徑不用選,在新建遠端專案的時候就已經確定,Absolute path on the server則是遠端主機的Web路徑。在途中紅框上方有一個Validate remote environment可以用來驗證遠端的Xdebug配置,如果配置明顯不對的話,會有提示資訊,可按照提示資訊修改遠端伺服器的xdebug配置。
3.5 配置除錯選項
由於除錯的目標是一個專案,所以這裡需要設定PHP Web Application,配置中Server:遠端目標主機,Start URL設為/,設定完之後會在左側新建一個PHP Web Application
到目前為止,該配置的都已經配置完成,這裡面配置的選項比較多,一步一步配置,有順序要求。配置完之後就是除錯。點選下圖右邊紅框中的小按鈕,開啟xdebug監聽,再選擇我們要除錯的目標,這裡是server,最後點選那個除錯按鈕,就能開啟除錯之旅。
開啟xdebug監聽的時候,可以看到IDE已經在本地建立監聽服務,具體如下:
可以看到除錯頁面。如下所示
3.6 瀏覽器新增書籤或者Xdebug Helper
前面描述的是通過PHPStorm的debug按鈕,傳送類似?XDEBUG_SESSION_START=17212
這種請求調起瀏覽器來達到除錯的目的,但是這種方式只能調起首頁,存在缺陷。下面介紹另外一種啟動除錯的方式,就是通過瀏覽器中帶XDEBUG_SESSION
的cookie直接發起,可以安裝Chrome外掛Xdebug Helper或者新增瀏覽器的除錯外掛、或書籤來達到目的。新建書籤的url:https://www.jetbrains.com/phpstorm/marklets/,這裡就不再做示例,外掛和書籤的原理都是一樣的,都是在cookie中新增XDEBUG_SESSION=PHPSTORM。
4 資料流程
前面的配置完全是一個操作指南,如果僅僅是為了配置,上面的內容已經足夠,但是如果配置中遇到什麼問題,就需要接下來的原理分析。古人說的好,我們得知其然還得知其所以然。
4.1 Xdebug工作原理
1,IDE(如PhpStorm)已經集成了一個遵循BGDP的Xdebug外掛,當開啟它的時候, 會在本地開一個xdebug除錯服務,監聽在偵錯程式中所設定的埠上,預設是9000,這個服務就會監聽所有到9000埠的連結。在PhpStorm中,位於:工具欄 > Run > Start / Stop Listening for PHP Xdebug Connetions。
2,當瀏覽器傳送一個帶XDEBUG_SESSION_START的引數的請求到伺服器時,伺服器接受後將其轉到後端的php處理,如果php開啟了xdebug模組,則會將debug資訊轉發到客戶端IP的IDE的除錯埠上。當引數或者cookie資訊中不帶XDEBUG_SESSION_START,則不會啟動除錯。這就為後續在瀏覽器中新增開關提供了可能。
Xdebug的官方給出了一個示例圖:很好的展示了相互呼叫關係。
這個示例圖是綁定了ip,即使用了固定ip地址,xdebug.remote_connect_back = 0 ,也是 xdebug 的預設方式,這種情況下,xdebug 在收到除錯通知時會讀取配置 xdebug.remote_host 和 xdebug.remote_port ,預設是 localhost:9000,然後向這個埠傳送通知,這種方式只適合單一客戶端開發除錯。
另外一種方式則是不繫結IP,Xdebug根據請求來源(REMOTE_HOST)來發起除錯。示例圖如下:
那從使用者發起請求到,到IDE的整個流程圖如下:
當用戶的請求引數或者cookie中不帶除錯資訊,資料流就是瀏覽器到Apache(或其他web容器)到PHP,如果加上了除錯引數,則請求還會由PHP轉給Xdebug處理,Xdebug再把資訊轉發給IDE,完成除錯功能。
5 問題分析
由於拷貝了錯誤的Xdebug引數,導致走了不少彎路,如果僅僅是為了配置PhpStorm及Xdebug原理,關注前面部分即可。下面主要分析排除過程。
錯誤得配置如下:
zend_extension=xdebug.so
xdebug.idekey=PHPSTORM
#xdebug.remote_connect_back = 1 //如果開啟此,將忽略下面的 xdebug.remote_host 的引數
xdebug.remote_host=192.168.x.x //注意這裡是,客戶端的ip<即IDE的機器的ip,不是你的web server>
xdebug.remote_enable=on
xdebug.remote_port = 9001 //注意這裡是,客戶端的埠<即IDE的機器的ip,不是你的web server>
xdebug.remote_handler = dbgp
xdebug.auto_trace = 1
xdebug.collect_includes = 1
xdebug.collect_params = 1
;xdebug.collect_return = 1
xdebug.remote_autostart = 1
xdebug.remote_log = /tmp/xdebug.log
問題現象:
Apache反應奇慢無比,一個普通請求能耗時10分鐘,但是最終會有效應。
5.1 問題背景
本地環境:Windows7,遠端伺服器:Ubuntu14.04,這個遠端伺服器是本地環境下VMWare WorkStation下的一臺虛擬機器,網路連線方式是橋接。在除錯遠端專案時,作者使用的sftp來管理伺服器的資源,這裡面就會涉及到許可權的問題。
遠端伺服器只開了一個普通賬戶liaoxinxi,而/var/www 目錄以前是root許可權的,由於PhpStorm除錯時會在遠端伺服器web目錄下建立一個檔案,這必然會導致許可權問題,為了解決這個問題,執行chmod liaoxinxi:liaoxinxi /var/www -R
將web目錄修改為liaoxinxi使用者所有。
當然為了遠端除錯,我配置了xdebug.ini,這個配置引數當時也不是太清楚具體含義,比較著急,就從某篇號稱親手測試過可用的xdebug環境拷貝而來。下午比較混沌,當時做過的操作還挺多,xdebug這個配置我居然忘記我配過了,只記得修改了許可權相關內容。重啟Apache之後,web請求響應奇慢無比。
5.2 疑問點
5.2.1,許可權
當時一股腦的認為是許可權的問題,就又把web目錄許可權全改為777,還是奇慢無比,檢視apache日誌也沒有半點異常。
5.2.2 網路
無意之中發現在遠端伺服器上直接訪問,很快就能得到響應。這個遠端伺服器是我VMware下的虛擬機器,通過橋接模式與宿主機通訊。中午與其他同事討論這個問題的時候將問題排查點轉移到網路環境。懷疑是網路的問題,將橋接模式改成NAT,又是重啟虛擬機器,重啟宿主機,都不起作用。
5.2.3 Apache配置
於是又將矛盾轉移到Apache的配置上,Apache的配置檔案被我改動了很多回,當時覺得很簡單所以沒設定備份點,一個好的備份是多麼重要。只能重灌,這個在Ubuntu下還是很簡單的,一條命令搞定apt-get auto-remove --purge apache2
,並且刪除了原有的配置檔案。再通過apt-get重新安裝,apt-get install apache2
,重啟apache後發現在本地訪問,很快得到響應,不過響應的都是原始的php檔案,再安裝一下libapache2php模組,安裝完之後,響應還是一樣的奇慢無比。難道跟這個模組有關係,但是找不到相關資料。再翻看安裝apache2的輸出資訊時發現其重啟了xdebug模組,回想一下,是不是這些模組導致的問題呢?再仔細想想,那天下午好像還改了xdebug的配置,可能有問題。
5.2.4 Xdebug配置
回到Xdebug的配置檔案,其中一個配置xdebug.remote_host=192.168.*.* //這個配置是用來
,感覺峰迴路轉了,因為只有這個ip訪問就會奇慢無比,於是註釋掉,再重啟apache訪問,果然奇慢無比的問題解決了。
但是這又帶來一個新的問題,這個ip是我的本地環境,如果不配置的話怎麼除錯呢?於是將//後邊的內容用;註釋起來,前期一直以為//也是個註釋。//這種註釋方式在xdebug中不識別,所以根本不會向IDE所在機器傳送除錯包,會一直等到超時,所以就會特別慢。 再去除錯,在index.php下斷點,終於斷下來了。除錯的過程中發現,開啟或者未開啟除錯引數都會直接進入除錯模式,見了鬼了,回想起除錯流程圖,肯定出問題的地方在xdebug的配置,開啟配置檔案,果然發現一個相關引數
`xdebug.remote_autostart = 1`
這個引數的意思就是自動開啟遠端除錯,註釋掉就能接收不使用Xdebug除錯的引數。