调试的定义:经过必定方法,在程序中找到并减小缺陷的数量,从而使其能正常工做。
这里说一些如何调试PHP程序的经验。php
1、PHP自带的调试功能mysql
一、自带的报错功能sql
两个名词:开发环境是开发人员在进行开发和调试的环境,生产环境是最终客户在用的线上环境;
开发环境和生产环境要分开设置报错功能。数组
(1)开发环境
开发环境须要打开报错,如下是php.ini的配置项及其说明:网络
; This directive sets the error reporting level.
; Development Value: E_ALL | E_STRICT (Show all errors, warnings and notices including coding standards.)
error_reporting = E_ALL | E_STRICTsocket; This directive controls whether or not and where PHP will output errors,
; notices and warnings too. Error output is very useful during development.
; Development Value: On
display_errors = Onide
这样你在开发过程当中,能第一时间发现错误。函数
即便是一个低等级的报错“Notice: Undefined variable: a in E:\phpspace\test.php on line 14”,但一个未定义的变量的使用每每暗藏着bug。工具
你会问,若是我引进了开源的类库,他们抛出一堆的低等级错误怎么办?通常代码质量好的类库,也没有“Notice”级别的报错的。因此这也是鉴别一个类库质量的方法。单元测试
(2)生产环境
生产环境不能直接将错误输出,而是记入日志,如下是php.ini的配置项及其说明:
; It could be very dangerous in production environments.
; It's recommended that errors be logged on production servers rather than
; having the errors sent to STDOUT.
display_errors = Off; Besides displaying errors, PHP can also log errors to locations such as a
; server-specific log, STDERR, or a location specified by the error_log
; directive found below. While errors should not be displayed on productions
; servers they should still be monitored and logging is a great way to do that.
; Production Value: On
log_errors = On; Log errors to specified file.
error_log = /path/to/php_error.log
固然日志写到文件里只是一个选择,还有其余配置可参考手册。
生产环境是给客户提供服务的,你不可能在上面进行断点、打印输出等操做,因此日志是不错的选择。
二、其余一些语言特性、功能的使用
(1)少用错误控制运算符“@”
其的做用是,将“@”放置在一个PHP表达式以前,该表达式可能产生的任何错误信息都被忽略掉。
若是一个缺陷发生在这个表达式中,从PHP的输出中看不到任何错误,这增长了调试的难度。因此能不用则不用。
(2)有些函数自带有debug功能
好比这行代码:
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
开发者调试时已经肯定,$fp为空,链接失败,是这一行有问题,可是为何链接失败?
函数是php自带的,没法进行更深刻的调试。因此通常这样的函数(主要是网络通讯类的),会本身提供调试参数:$errno和$errstr。你能够加一句:
if (!$fp) echo "$errstr ($errno)<br />\n";
就能看到链接失败的缘由了。
这些函数有:fsockopen,pfsockopen,stream_socket_server,stream_socket_client 等。
还有些函数是调试一个功能用的,好比:mysql_errno,socket_last_error,socket_strerror 等。
这些只须要了解下,碰到能想到用便可。
2、引进调试工具
在遇到复杂问题时,能够借助调试工具。比较成熟的有Xdebug、ZendDebugger。
以Xdebug为例,它可以:控制打印输出的样式和数组层级、堆栈式的追踪错误、追踪函数调用、代码执行覆盖分析、程序的概要分析(Profiling)、远程调试。详见:http://xdebug.org/docs/。
Xdebug前两个功能是对PHP原有的调试功能作了改进,更方便调试。
复杂的问题,调试不出来的,多是业务上的的问题,下面也有说业务逻辑的调试。
3、调试业务逻辑错误
当PHP脚本跑起来,没有任何错误,只能说它没有语法上的错误,可是不能说明它业务逻辑上没错误。
不少业务逻辑的错误并不会反映在语法错误上,但调试的思路和PHP自带调试功能差很少。
下面是一些方法。
一、最基本的调试方法
先肯定两个东西:程序预期的结果、程序如今的不符合预期的结果;
寻找与两种结果相关的代码片断;
阅读这些代码片断,尝试以“肉眼”找出错误;
找不出,则须要输出一些关键变量,经过检查它们的值是否正确来判断是哪里发生了错误;
若干次尝试,最终你能够肯定错误发生在哪一个点。
你也能够借助Xdebug等工具,查看变量值的变化,或者设置断点进行调试。
二、记录运行日志
有些复杂或特殊的业务,用上面的方法不合适,好比:一个不能被打断的后台运行脚本。这些状况下记录运行日志比较合适。
记日志的点要有所选择,除了业务上比较重要的点,一般容易出错的地方有:网络链接和通讯、系统权限问题等。
三、单元测试
以代码测试代码,而不是像第一点同样调试完会把测试代码丢掉。以测试驱动开发。
这个话题比较大,但适合放这里提一下。有兴趣的同窗能够去了解。
4、调试非功能性的错误
非功能性错误,好比:内存溢出致使程序挂掉了、效率有问题致使程序很是慢、死循环了等等。
这些问题,用“肉眼”检查代码效率过低了。
因此能够借助调试工具作程序的概要分析(Profiling),从中检查出程序的瓶颈所在。