做php開發時間不短了,在這裏總結下平時常用的調試方法,希望對大家有所幫助。
1 代碼調試
1.1 打印輸出
使用echo、var_dump 、print_r等方法在需要調試地方進行打印輸出,通過輸出特定變量的值可以判斷程序執行是否正確。
1.2 使用debug_backtrace
函數打印調用棧信息:
debug_print_backtrace();exit;
#0 cli_rakuten->getOrders(1)
#1 call_user_func_array(Array ([0] => cli_rakuten Object (),[1] => getOrders), Array ([0] => 1)) called at [/data/project/***/include/of/of.php:79]
#2 of::cliDispatch(cli_rakuten, getOrders, 1, Array ([0] => 1)) called at [/data/project/***/cli.php:17]
1.3 使用xdebug調試代碼
Xdebug是一個開放源代碼的PHP程序調試器(即一個Debug工具),可以用來跟蹤,調試和分析PHP程序的運行狀況。
配置好phpstorm+xdebug後,可很方便的對代碼進行斷點調試:
除了生成調用棧信息外,xdebug還能生成性能分析報告,windows上可使用WinCacheGrind來查看性能分析報告。
1.4 使用xhprof調試分析代碼
XHProf是facebook 開發的一個測試php性能的擴展。
對於本地開發環境來說,進行性能分析xdebug
是夠用了,但如果是線上環境的話,xdebug
消耗較大,配置也不夠靈活,因此線上環境建議使用xhprof進行PHP性能追蹤及分析。
xhprof安裝很簡單,可直接去搜索安裝文檔。
在代碼中加入生成xhprof分析報告代碼:
xhprof_enable(
XHPROF_FLAGS_MEMORY|XHPROF_FLAGS_CPU,
[
'ignored_functions' => [
'call_user_func',
'call_user_func_array'
]
]);
//這裏是業務代碼
//...
$xhprofData = xhprof_disable();
require '/data/soft/xhprof/xhprof_lib/utils/xhprof_lib.php';
require '/data/soft/xhprof/xhprof_lib/utils/xhprof_runs.php';
$xhprofRuns = new XHProfRuns_Default();
$runId = $xhprofRuns->save_run($xhprofData, 'xhprof_test');
echo 'http://192.168.52.129:8888/xhprof_html/index.php?run=' . $runId . '&source=xhprof_test'.PHP_EOL;
查看報告:
圖形報告:
2 日誌分析
log日誌,通常是系統或軟件、應用的運行記錄。通過log的分析,可以方便用戶瞭解系統或軟件、應用的運行情況;如果你的應用log足夠豐富,也可以分析以往用戶的操作行爲、類型喜好、地域分佈或其他更多信息;如果一個應用的log同時也分了多個級別,那麼可以很輕易地分析得到該應用的健康狀況,及時發現問題並快速定位、解決問題,補救損失。
2.1 PHP日誌
2.1.1 php錯誤日誌
php錯誤日誌可在配置文件php.ini中設置:
log_errors = On
error_log = /var/log/php-fpm/php_errors.log
也可在php-fpm配置文件php-fpm.conf中設置:
php-fpm進程日誌,記錄php-fpm進程相關日誌信息
error_log = /var/log/php-fpm/error.log
php-fpm.conf中也可以設置錯誤日誌,會覆蓋掉php.ini中的相關設置
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
2.1.2 php慢日誌
slowlog = /var/log/php-fpm/www-slow.log
#執行時間超過request_slowlog_timeout 設置時間將會記錄到slowlog中
request_slowlog_timeout = 1s
慢日誌文件中會記錄執行時間較長的函數信息:
[19-Sep-2018 11:00:55] [pool www] pid 80603
script_filename = /data/project/test//slow.php
[0x00007f4e0a7ed568] sleep() /data/project/test/slow.php:5
2.2 業務日誌
php內置error_log、syslog函數功能強大且性能極好,但由於各種缺陷(error_log無錯誤級別、無固定格式,syslog不分模塊、與系統日誌混合),靈活度降低了很多,不能滿足應用需求。
當然我們可以自己封裝實現一個符合PHP PSR-3 日誌接口規範 所要求的模塊、級別、清晰、易用等特點的日誌庫,但通常不建議這樣做,因爲已經有一些非常好的第三方日誌庫了,我們可直接用。
這裏挑選3款應用比較廣的日誌庫進行比較:
log4php
文檔:http://logging.apache.org/log4php/quickstart.html
log4php是apche組織維護項目,是log4xx系列日誌組件之一,log4j在JAVA中可算是大名鼎鼎的日誌開發包。log4php也作爲一個單獨的子項目存在,可以很方便的加載使用。
優點:
最爲著名、設計精良、格式完美、文檔完善、功能強大、擴展方便
缺點:
只支持TRACE、DEBUG、INFO、WARN、ERROR、FATAL共6個日誌級別,不完全符合psr-3日誌規範
停止維護了,目前最新版本還是更新於2012-12-13日v2.3.0
性能較差
Monolog
github地址:https://github.com/Seldaek/monolog
使用方法:https://www.jianshu.com/p/59ce6d70f801
Monolog是一款強大的日誌處理類庫,應用非常廣泛,目前有包括Symfony 、Laravel、 CakePHP、YII等諸多知名php框架都內置了Monolog。Monolog可以發送你的日誌到文件、到sockets、到郵箱、到數據庫或(和)者其他網路存儲服務(雲)。這裏用了或與和,因爲Monolog的確可以做到同時保存到一個或多個存儲介質。
優點:
功能強大、應用廣泛、安裝方便、設計優秀,使用靈活、擴展方便、更新活躍
缺點:性能較差
SeasLog
github地址:https://github.com/Neeke/SeasLog
使用方法:https://blog.csdn.net/u011120720/article/details/51474488
SeasLog是一個C語言編寫的PHP擴展,提供一組規範標準的功能函數,在PHP項目中方便、規範、高效地寫日誌,以及快速地讀取和查詢日誌。
優點:高性能、功能完善
缺點:
安裝配置較麻煩,如編譯PHP擴展
擴展不方便
比較
從功能上比較:
Monolog > SeasLog > log4php
從性能上比較:
SeasLog > Monolog > log4php
3 進程跟蹤
3.1 使用lsof查看進程打開的文件句柄
Linux平臺提供了lsof
工具可以查看某個進程打開的文件句柄,可以用於跟蹤進程所有打開的socket、file、資源。
lsof -p 2901
3.2 使用strace跟蹤進程中的系統調用
strace常用來跟蹤進程執行時的系統調用和所接收的信號。 在Linux世界,進程不能直接訪問硬件設備,當進程需要訪問硬件設備(比如讀取磁盤文件,接收網絡數據等等)時,必須由用戶態模式切換至內核態模式,通過系統調用訪問硬件設備。strace可以跟蹤到一個進程產生的系統調用,包括參數,返回值,執行消耗的時間。
跟蹤可執行程序:
strace -T -tt -s 512 php /data/project/***/cli.php test
跟蹤服務程序
strace -T -tt -s 512 -p 1123
默認返回的結果每一行代表一條系統調用,規則爲“系統調用的函數名及其參數=函數返回值”。
3.3 gdb調試php進程
一般的php問題通過以上的這些方法排查出來了。但還有死循環、進程異常退出等問題可通過gdb分析core dump文件來排查原因。
//修改core file size
ulimit -c unlimited
//修改core dump文件生成位置
echo "/tmp/core-%e.%p" > /proc/sys/kernel/core_pattern
//用gdb調試core dump文件
gdb php -c core.31656
4 網絡抓包
4.1 使用tcpdump抓包
在調試網絡通信程序是tcpdump是必備工具。tcpdump很強大,可以看到網絡通信的每個細節。如TCP,可以看到3次握手,PUSH/ACK數據推送,close4次揮手,全部細節。包括每一次網絡收包的字節數,時間等。
tcpdump -i any tcp port 80
- 18:01:37.968224 時間帶有精確到微妙
- 192.168.52.1.64504 > T1.http 表示通信的流向,64504是客戶端,T1.http是服務器端80端口
- [S] 表示這是一個SYN請求
- [.] 表示這是一個ACK確認包,(client)SYN->(server)SYN->(client)ACK 就是3次握手過程
- [P] 表示這個是一個數據推送,可以是從服務器端向客戶端推送,也可以從客戶端向服務器端推
- [F] 表示這是一個FIN包,是關閉連接操作,client/server都有可能發起
- [R] 表示這是一個RST包,與F包作用相同,但RST表示連接關閉時,仍然有數據未被處理。可以理解爲是強制切斷連接
- win 2053是指滑動窗口大小
- length 7300指數據包的大小
4.2 使用ngrep抓包
tcpdump能抓到網絡通信細節,但如果只想看傳輸的數據等簡單信息可以用ngrep命令
ngrep -pqt -W byline port 80 -d ens33