PHP程序员优化调试技术和技巧
PHP程序员优化调试技术和技巧
本文介绍调试PHP应用程序的各种方法,包括在ApacheandPHP中打开错误报告,以及通过在一个简单的PHP脚本中放置策略性的print语句,找到更困难的bug的源头。还会介绍用于Eclipse的PHPEclipse插件,这是一个灵活的开发环境,具有实时语法解析能力,还会介绍PHPEclipse的DBG调试器扩展。
简介
有许多PHP调试技术可以在编码的时候节约大量时间。一个有效却很基本的调试技术就是打开错误报告。另一个略微高级一点的技术包括使用print语句,通过显示在屏幕上实际出现的内容,有助于精确地找出更难发现的bug。PHPEclipse是一个Eclipse插件,能够强调常见的语法错误,可以与调试器结合起来用于设置断点。
设置
要学习本文描述的概念,需要PHP、Web服务器和Eclipse。调试器扩展支持的PHP版本是V5.0.3。
我们需要一个Web服务器来解析用PHP创建的页面并把它们显示到浏览器。本文中使用的是Apache2。但是,任何Web服务器都可以满足要求。
要利用本文中介绍的一些调试技术,需要安装EclipseV3.1.1和插件PHPEclipseV1.1.8。由于Eclipse要求Java?技术,所以还要下载它。
还需要PHP的调试器扩展模块。安装它略有些麻烦。请仔细跟随安装调试器扩展的操作说明。现在,先在php.ini文件中注释掉那些要求装入和配置PHP扩展的行。在需要使用调试器的时候,再取消注释。
现在介绍出错消息。
出错消息
出错消息是作为开发人员的第一道防线。谁都不想在一台没有配置成显示出错消息的服务器上用PHP开发代码。但是,请记住,当代码调试完成,准备运行的时候,应当确保关闭了错误报告,因为不希望站点的访问者看到出错消息,因为这会给他们提供足够的信息来利用站点的弱点并黑掉站点。
也可以用出错消息为自己服务,因为它们会显示抛出或生成错误的正确代码行。这样,调试就变成在浏览器上查看生成的错误所显示的行号,并在代码中检查这一行。稍后,将会看到PHPEclipse插件通过即时地给语法错误加下划线并在保存文件时用红色“x”标注语法错误,可在开发和调试过程中提供极大的帮助。
先来看如何在php.ini文件中开启错误报告并设置错误报告的级别。然后将学习如何在Apache的配置文件中覆盖这些设置。
PHP的错误报告
php.ini文件中有许多配置设置。您应当已经设置好自己的php.ini文件并把它放在合适的目录中,就像在Linux上安装PHP和Apache2的文档说明中所示的那样)。在调试PHP应用程序时,应当知道两个配置变量。下面是这两个变量及其默认值:
display_errors=Off
error_reporting=E_ALL
通过在php.ini文件中搜索它们,可以发现这两个变量当前的默认值。display_errors变量的目的很明显——它告诉PHP是否显示错误。默认值是Off。但是,要让开发过程更加轻松,请把这个值设为On:
display_errors=On
error_reporting变量的默认值是E_ALL。这个设置会显示从不良编码实践到无害提示到出错的所有信息。E_ALL对于开发过程来说有点太细,因为它在屏幕上为一些小事(例如变量未初始化)也显示提示,会搞糟浏览器的输出。我只想看到错误和不良编码实践,但是不想看到无害的提示。所以,请用以下值代替error_reporting的默认值:
error_reporting=E_ALL&~E_NOTICE
重新启动Apache,就全部设置好了。接下来,将学习如何在Apache上做同样的事。
服务器上的错误报告
依赖于Apache正在做的工作,在PHP中打开错误报告可能没法工作,因为在计算机上可能有多个PHP版本。有时很难区分Apache正在使用哪个PHP版本,因为Apache只能查看一个php.ini文件。不知道Apache正在使用哪个php.ini文件配置自己是一个安全问题。但是,有一种方法可以在Apache中配置PHP变量,从而保证设置了正确的出错级别。
而且,最好知道如何在服务器端设置这些配置变量,以否决或抢占php.ini文件,从而提供更高级别的安全性。
在配置Apache时,应该已经接触过<apache2-install-dir>/conf/httpd.conf中http.conf文件中的基本配置。
要做在php.ini文件中已经做过的事,请把下列各行添加到httpd.conf,覆盖任何php.ini文件:
php_flagdisplay_errorson
php_valueerror_reporting2039
这会覆盖在php.ini文件中为display_errors已经设置的标志,以及error_reporting的值。值2039代表E_ALL&~E_NOTICE。如果愿意采用E_ALL,请把值设为2047。同样,还是要重启Apache。
接下来,要在服务器上测试错误报告。
测试错误报告
如果启动了错误报告,会节约许多时间。PHP中的错误会指向代码中的错误。请创建一个简单的PHP文件test.php,并像清单1所示一样定义它。
清单1.一个生成错误的简单PHP
<?php
print("Thenextlinegeneratesanerror.<br>");
printaline("PLEASE?");
print("Thiswillnotbedisplayedduetotheaboveerror.");
?>
第一个print()语句会向Web浏览器显示它的内容。但是第二个语句会生成错误并在Web页面上显示。这造成最后一个print()语句不起作用,如图1所示。
图1.生成错误
现在开启了错误报告!接下来,用print语句帮助调试应用程序。
介绍print语句
因为应用程序中的功能性bug不会产生错误,所以在所有调试策略中,关于如何正确地放置和使用print或die语句来调试PHP应用程序的知识是一种很好的资产。可以用print语句在代码中缩小对问题语句的定位,这些语句在语法上没有错误,也不是bug,但是从代码的功能上看是bug。这些是最难发现和调试的bug,因为它们不会抛出错误。惟一知道的就是在浏览器上显示的内容不是想要的内容,或者想要保存在数据库中的内容根本没有保存。
假设正在处理通过GET请求发送过来的表单数据,想向浏览器显示信息,但是出于某种原因,数据没有正确地提交,或者不能正确地从GET请求中读出。要调试这类问题,重要的是用print()或die()语句知道变量的值是什么。
die()语句会中止程序执行,并在Web浏览器上显示文本。如果不想注释掉代码,而且只想显示到出错之前的信息和出错信息,不想显示后面的信息,那么die()语句特别有用。
让我们在PHP中用print语句来测试这个概念
使用print语句进行调试
在我作程序员的那些时候,当我在Linux?上开发应用程序时,没有方便的GUI可以告诉我bug在哪,我迅速地发现我在程序中放的print语句越多,我在应用程序中把bug的范围缩小到一行的机会越大。请创建另一个PHP文件test2.php,并像清单2所示的那样定义它。
清单2.显示通过GET提交的所有变量
<?php
$j="";
print("Letsretrieveallthevariablessubmittedtothis");
print("scriptviaaGETrequest:<br>");
foreach($_GETas$key=>$i){
print("$key=$j<br>");
}
if($_GET[