当前位置: 首页 > 图文教程 > 网络编程 > PHP > PHP程序员的优化调试技术和技巧

PHP
php 多线程上下文中安全写文件实现代码
PHP类的使用 实例代码讲解
用php实现让页面只能被百度gogole蜘蛛访问的方法
php 学习笔记
PHP编程过程中需要了解的this,self,parent的区别
php 操作excel文件的方法小结
使用PHP获取网络文件的实现代码
PHP 巧用数组降低程序的时间复杂度
php下将XML转换为数组
php 文件上传代码(限制jpg文件)
php 无极分类(递归)实现代码
PHP 采集获取指定网址的内容
PHP 将图片按创建时间进行分类存储的实现代码
PHP 存储文本换行实现方法
PHP 批量更新网页内容实现代码
用PHP查询搜索引擎排名位置的代码
用php实现的获取网页中的图片并保存到本地的代码
php实现首页链接查询 友情链接检查的代码
处理php自动反斜杠的函数代码
php实现的遍历文件夹下所有文件,编辑删除

PHP程序员的优化调试技术和技巧


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-23   浏览: 94 ::
收藏到网摘: n/a

本文介绍调试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=Offerror_reporting=E_ALL

通过在php.ini文件中搜索它们,可以发现这两个变量当前的默认值。display_errors变量的目的很明显——它告诉PHP是否显示错误。默认值是Off。但是,要让开发过程更加轻松,请把这个值设为bgColor=#e3e3e3border=1>
display_errors=bgColor=#e3e3e3border=1>
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_errorsbgColor=#e3e3e3border=1>
<?phpprint("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['Submit']=="SendGETRequest")$j="done!<br>";?><formmethod="GET">Name:<inputname="name"><br>Email:<inputname="email"size="25"><br><inputname="Submit"type="submit"value="SendGETRequest"></form>

您可能会非常容易地发现清单2中的bug!您很棒!但请注意这是一个非常简单的脚本,只是作为使用print语句进行调试而展示的一个例子而已。这个脚本只是提取GET请求中的所有变量,如果有,就把它们显示在浏览器上。还提供了一个表单,用GET请求向服务器发送变量以进行测试。请看输出,如图2所示。

图2.test2.php的输出


现在单击SendGETRequest按钮,请注意只有$_GET请求的键显示在浏览器上,而正确的值都没显示。可以在循环中放一个print语句,检验在foreach循环中每个元素中是否确实存在数据。请参阅清单3。

清单3.用print语句验证代码的功能
...foreach($_GETas$key=>$i){print("Correctdata?".$_GET[$key]."<br>");print("$key=$j<br>");}...


放进去的print语句是粗体。注意,现在已经知道在Web浏览器上显示的$key值是正确的,但是由于某些原因,值没有正确地显示。请看新的输出,如图3所示。

图3.修改后的test2.php的输出


现在已经知道应用程序正确地从GET请求接收到了变量,那么肯定是在代码中有bug。查看之后注意到,用来显示值的变量$j是错误的。在foreach语句中指定的是$i,所以它肯定会有正确的值,但是无意之中输入了$j。所以通过把$j替换成$i,迅速地修正了错误,重新载入页面之后,就看到了正确的输出,如图4所示。

图4.修正后的test2.php的输出


现在可以删除或注释掉刚才添加的print语句了,因为已经发现了代码中的bug。注意,这只是在调试应用程序时可能遇到的许多错误中的一个很小的子集。对于使用数据库时可能遇到的问题,一个好的解决方案是输出SQL语句,以确保执行的SQL就是想要执行的。

现在要来看看如何使用EclipseIDE和PHPEclipse插件及调试器扩展进一步在调试历程中提供帮助。

使用PHPEclipse

您可能用过Eclipse,但是可能不熟悉它。请参阅参考资料获得Eclipse平台的介绍。

用于Eclipse的PHPEclipse插件是用来开发PHP应用程序的一个流行工具。请启动Eclipse并把工作区目录指定为Apache的www目录(在我的机器上是c:\www)。现在单击File>New>Project。会弹出NewProject向导。双击PHP文件夹并选择PHPProject。单击Next,输入项目名称debugArticle,并单击Finish

如果把Web服务器设置为在端口80上侦听,那么不需要做任何修改。否则,请转到Navigator窗口,在PHP项目debugArticle上右击,选择Properties,然后单击PHPProjectSettings。单击ConfigureWorkspaceSettings然后修改合适的localhost或者添加Web服务器侦听的端口(例如http://localhost:8080)。单击Apply完成设置。

Navigator窗口应当显示项目和一个.project文件。在项目上右击,就像前面做的那样,只是这次选择New>PHPFile。用想要创建的PHP文件的名称test3.php替换*.php,然后单击Finish。在EclipseIDE中应当出现一个新文件。可能需要导航到窗口底部的PHP浏览器来查看PHP文件的当前输出(参见图5)。

图5.Eclipse的PHPEclipse插件


注意,只有Windows?的用户可以像清单5所示的那样使用PHP浏览器。通过打开独立浏览器窗口并把浏览器指向测试脚本所在目录,也可以使用同样的功能。

现在来演示这个应用程序,证明它的强大能力。

在“使用调试器”一节中,将学习如何用Eclipse、PHPEclipse和前面下载的调试器PHP扩展来调试PHP应用程序。先从学习如何使用它的语法解析功能开始。

语法解析和加下划线

先从查看PHPEclipse如何提供帮助调试PHP应用程序的实时语法解析功能开始。要看这个特性的实际应用,先从在Eclipse中定义test3.php开始,如下所示。

<?phpprint(,"HelloWorld!");?>


注意,在清单4中加下划线的两个字符在Eclipse中加了下划线,提示语法不正确。按Ctrl+S保存文件,会在Eclipse中显示解析错误:在代码中与解析错误对应的行上会加上红“x”,如图6所示。

图6.语法错误强调


现在演示PHP浏览器。这个窗口提供了当前PHP脚本的预览,如图6所示。

从上面定义的test3.php中删除逗号(,)。按Ctrl+S保存文件,然后观察PHP浏览器窗口的更新,显示了HelloWorld(参见图7)。

图7.在PHPEclipse中预览PHP脚本


下面是用调试器在PHP中设置断点。

使用调试器

使用调试器,可以设置断点并查看PHP代码到所设断点之前的浏览器输出。然后可以继续代码的执行并查看到下一断点之前的浏览器输出,然后再到下一个,直到PHP脚本完成。

现在把“设置”一节中在php.ini中注释掉的行取消注释,并重新启动Apache。现在装入了调试器,Eclipse能够和它挂上了。

现在在Eclipse中设计调试环境。请创建新的test4.php文件,先保持为空。现在单击Run>Debug。在左侧面板中选择PHPDBGScript,并单击New。现在转到File选项卡,输入当前项目debugArticle以及想要调试的文件test4.php。现在转到Environment选项卡,然后再到Interpreter子选项卡。在PHP的安装目录中找到php.exe文件(我的是c:\apps\php5.0.3\php.exe)。现在单击RemoteDebug子选项卡,选择RemoteDebug,如果没有使用Windows,请取消“OpenwithDBGSessionURLininternalbrowserbox”复选框。把RemoteSource路径设置成与要测试的PHP脚本的绝对路径(不是Web路径)相同(我的设置是c:\www\debugArticle\test4.php)。现在单击Debug

现在应当装入Debug透视图,如图8所示。否则,请单击Window>OpenPerspective>Other,并选择Debug

图8.Eclipse中的Debug透视图


现在可以设置断点了。

对于本文中使用的插件和扩展的版本,断点功能是必需的,因为PHP在把输出发送到浏览器之前会缓冲它。除此之外,需要做的不仅仅是设置一个断点把当前显示数据刷新到Web浏览器,所以要像下面和图8所示那样定义test4.php。

清单4.设置和创建断点
<?phpfunctionbreak-point(){ob_flush();flush();sleep(.1);debugBreak();}print("Thiswillgetshownfirst,");print("aswillthis<br>");breakpoint();print("Thiswon'tgetshownuntilafter");print("continuingthebreak-point<br>");breakpoint();print("END!");?

breakpoint()函数会把缓冲的输出和其他缓冲的数据刷新到Web浏览器。对sleep(.1)的调用是必需的,这样代码中止于debugBreak()之前,服务器才有足够的时间把数据刷新到Web浏览器,这个函数是前面下载的PHP调试器扩展的内部函数。这样,调用breakpoint()会把HTML块、print()和echo()语句的数据刷新到浏览器,然后中止代码执行。

在像清单4那样编写完代码之后,可以打开浏览器并指向test4.php,或者可以查看PHP浏览器窗口(我的是http://localhost/debugArticle/test4.php)。每次输入和保存文件时,在PHP浏览器窗口中就已经启动了调试序列。如果不使用Windows,请通过浏览器查看test4.php。在保存了文件之后,用F8或单击Run>Resume继续代码执行。持续这么做,直到最后一行输出是END!为止(参见图9、10和11)。

图9.初始的到第一个断点的PHP浏览器输出


请注意图9中的Debug窗口如何把执行显示为挂起的。

图10.第一个断点之后到第二个断点之前的PHP浏览器输出


图10的Debug窗口仍然把执行显示为挂起,而第二组数据显示在PHP浏览器中。

图11.完整的PHP浏览器输出


注意,图11的Debug窗口中的代码不再挂起,整个脚本已经执行,如图11中的PHP浏览器所示。

既然已经看到了用PHPEclipse和调试器扩展进行开发的优势,那么很难想像没有它会怎么样。

结束语

现在已经向PHP的调试技术集中添加了错误报告的运用、print语句、PHPEclipse和调试器扩展,您可以通过减少每行代码的错误数量,成为更有效的PHP编码人员。请参阅参考资料获得一些PHP教程,可以在上面测试这些新技能。