Home > Article > Backend Development > php怎么调试排错?
做php开发时间不短了,在这里总结下平时常用的调试方法,希望对大家有所帮助。
1 代码调试
1.1 打印输出
使用echo、var_dump 、print_r等方法在需要调试地方进行打印输出,通过输出特定变量的值可以判断程序执行是否正确。
1.2 使用<span style="font-size: 16px;">debug_backtrace</span>
函数打印调用栈信息:
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调试代码
PHP 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
4.2 使用ngrep抓包
tcpdump能抓到网络通信细节,但如果只想看传输的数据等简单信息可以用ngrep命令
ngrep -pqt -W byline port 80 -d ens33
更多相关知识,请访问 PHP中文网!!