xdebug配置.docx
《xdebug配置.docx》由会员分享,可在线阅读,更多相关《xdebug配置.docx(6页珍藏版)》请在冰豆网上搜索。
xdebug配置
xdebug配置
虽然您可以使用PHP为系统管理和传统数据处理之类的任务创建命令行脚本,但是编程语言对Web应用程序的性能有主要影响。
在使用过程中,每个PHP应用程序都驻留在服务器上,并且将通过代理(例如Apache)调用PHP应用程序处理到来的请求。
对于每个请求,典型的PHPWeb应用程序在简短运行后将得到一个Web页面或XML数据结构。
假定经过简单的运行后,一个分层构造的Web应用程序——包括客户机、网络、HTTP服务器、应用程序代码和底层数据库——将会很难隔离PHP代码中的错误。
即使假定除了PHP代码以外所有层都可以正常运行,跟踪PHP代码中的错误也会非常难,尤其是在应用程序利用较多的类时更是如此。
PHP语句echo和函数var_dump()、debug_zval_dump()和print_r()都是常见且流行的调试辅助工具,可以帮助解决多种问题。
但是,这些语句——甚至更健壮的工具,例如PEARLogpackage——都是取证工具,必须在上下文环境之外先进行推测分析才能生成证据。
在某种程度上,通过推论进行调试是一种蛮干的做法。
收集并筛选数据,尝试推论出发生的问题。
如果缺少重要信息,则必须重新测试代码、重复执行步骤,然后重新开始研究。
一种更加高效的方法是在程序运行时探测应用程序。
您可以对请求参数分类,筛选过程调用堆栈,并查询任何所需的变量或对象。
您可以暂时中断应用程序并且可以在变量更改值时收到警报。
在某些情况下,您可以通过交互式询问“如果……会怎样?
”问题来实际影响变量。
称为调试器的特殊应用程序支持这种“实时的”或交互式的检查。
调试器可能启动并连接到进程上以便控制进程并监测其内存。
或者,在使用解释语言的情况下,调试器可以直接解释代码。
典型的现代图形化调试器可以索引并浏览代码,以符合人类阅读习惯的形式轻松地显示复杂的数据结构,并同时显示程序状态,如调用堆栈、中间输出和所有变量的值。
例如,调试器通常都会把类的属性和方法分类并进行描述。
在本文和下一篇文章中,我将介绍的工具一定能够简化PHP调试。
下一次,我将主要介绍交互式调试和ZendDebugger——一个特别针对PHP的健壮调试器——并探究它提供的许多功能。
(ZendDebugger是一款商业产品,是ZendPHP集成开发环境(IDE)的一部分)。
我还将介绍一款开源PHP调试器,以免您只愿把钱花在啤酒上,而不是花在代码上。
但是,本文将主要介绍如何更好地取证。
类似《犯罪现场调查》,只是更令人讨厌 代码出错、未能生成某个所需结果或者彻底崩溃时,您需要回答四个w问题:
where、what、why和when:
“where”是应用程序最后一次正常运行时所在的文件和行号。
“what”是犯错的代码——比如说,嫌疑犯。
“why”是错误的本质。
可能它是一个逻辑错误和/或与操作系统进行交互所导致的错误,或两者兼具。
而“when”是出现错误时的上下文。
在程序终止前发生了什么情况?
像在所有犯罪行为中一样,如果您可以收集到足够的线索,那么线索就可以帮助您找到犯人。
一种取证工具Xdebug(上一篇文章中使用的工具,用于分析PHP应用程序性能),如名称所示,将提供几个说明程序状态的功能,并且是应当添加到指令系统中的价值颇高的研究工具(请参阅参考资料)。
安装后,Xdebug将阻止无限次递归(表面上是这样)、修正关于堆栈跟踪和函数跟踪的错误消息以及监视内存分配,并提供其他功能。
Xdebug还包括一组函数,您可以将这组函数添加到代码中以进行运行时错误诊断。
例如,下面的代码将使用一些xdebug_...()步骤测试callee()函数,以便输出调用程序的具体位置,包括文件名、行号和调用函数的名称。
清单1.测试callee()函数的步骤 functioncallee($a){ echosprintf("callee()called@%s:
%sfrom%s", xdebug_call_file(), xdebug_call_line(), xdebug_call_function() ); } $result=callee("arg"); ?
> 这段代码将生成:
callee()called@/var/www/catalog/xd.php:
10from{main} 回页首构建和安装Xdebug Xdebug可以很轻松地从UNIX?
类操作系统(包括MacOSX)中的源代码构建。
如果是在Microsoft?
Windows?
上使用PHP,则可以从XdebugWeb站点下载最新PHP版本的二进制Xdebug模块(请参阅参考资料)。
让我们来构建和安装适用于Debian“Sarge”Linux?
和PHPV4.3.10-19的Xdebug。
在撰写本文时,Xdebug的最新版本是V2.0.0RC4,发布于2007年5月17日。
要继续本文,必须拥有phpize和php-config实用程序,并且必须能够编辑系统的php.ini配置文件(如果没有实用程序,请访问PHP.net以获得如何从头构建PHP的源代码和说明)。
请执行以下步骤:
下载Xdebugtarball(一个用gzip压缩的.tar归档文件)。
wget命令可以帮助您轻松地完成此操作:
$wgethttp:
//www.xdebug.org/files/xdebug-2.0.0RC4.tgz 解压缩该tarball并切换到源代码目录:
$tarxzfxdebug-2.0.0RC4.tgz $cdxdebug-2.0.0RC4 运行phpize以准备适用于您的PHP版本的Xdebug代码:
$phpize Configuringfor:
PHPApiVersion:
20020918 ZendModuleApiNo:
20020429 ZendExtensionApiNo:
20021010 phpize的输出是一个脚本——通常名为配置——用于调整其余的构建过程。
运行配置脚本:
$./configure checkingbuildsystemtype...i686-pc-linux-gnu checkinghostsystemtype...i686-pc-linux-gnu checkingforgcc...gcc checkingforCcompilerdefaultoutputfilename...a.out checkingwhethertheCcompilerworks...yes checkingwhetherwearecrosscompiling...no checkingforsuffixofexecutables... checkingforsuffixofobjectfiles...o ... checkingwhetherstrippinglibrariesispossible...yes appendingconfigurationtag"F77"tolibtool configure:
creating./config.status config.status:
creatingconfig.h 通过运行make构建Xdebug扩展:
$make /bin/sh/home/strike/tmp/xdebug-2.0.0RC4/libtool --mode=compilegcc-I. -I/home/strike/tmp/xdebug-2.0.0RC4-DPHP_ATOM_INC -I/home/strike/tmp/xdebug-2.0.0RC4/include -I/home/strike/tmp/xdebug-2.0.0RC4/main -I/home/strike/tmp/xdebug-2.0.0RC4 -I/usr/include/php4-I/usr/include/php4/main -I/usr/include/php4/Zend-I/usr/include/php4/TSRM -DHAVE_CONFIG_H-g-O0-c /home/strike/tmp/xdebug-2.0.0RC4/xdebug.c-o xdebug.lomkdir.libs ... Buildcomplete. (Itissafetoignorewarningsabouttempnamandtmpnam). 使用make将生成Xdebug扩展xdebug.so。
安装该扩展:
$sudomakeinstall Installingsharedextensions:
/usr/lib/php4/20020429/ 继续之前,使用鼠标选择并复制上一条命令显示的目录。
该路径对于最后一步配置扩展至关重要。
在您喜欢的文本编辑器中打开php.ini文件,然后添加以下代码:
zend_extension=/usr/lib/php4/20020429/xdebug.so xdebug.profiler_enable=Off xdebug.default_enable=On 第一行将装入Xdebug扩展;第二行将禁用Xdebug的分析器功能(只是为了简单起见),而第三行将启用扩展的调试功能。
要检验Xdebug扩展是否已经安装并启用,请重新启动Web服务器,然后用代码创建简单的一行PHP应用程序。
如果将浏览器指向文件——如http:
//localhost/phpinfo.php——并向下滚动,您应当会看到类似图1所示的内容。
图1.检验Xdebug扩展是否已经安装并运行 注:
如果您在phpinfo()的输出中没有看到Xdebug部分,则Xdebug装入失败。
Apache错误日志会列出原因。
常见错误包括zend_extension的路径错误或者与其他扩展发生冲突。
例如,如果需要使用XCache和Xdebug,一定要先装入XCache。
但是,由于Xdebug适于在开发时使用并假定xdebug.so的路径正确,因此需要禁用其他扩展并重试。
然后您可以重新启用扩展以执行其他测试,如缓存的效果。
Xdebug站点还有其他一些故障检修技巧。
回页首配置Xdebug 指令(图1中大表的最左侧一列)是一些可以设定的参数,用于改变Xdebug扩展的行为。
可在php.ini文件中设置所有指令。
一些指令用于配置调试工具;其他指令用于调整分析器的操作。
忽略后者,让我们用一些合理设置来配置Xdebug以帮助调试PHP代码。
限制递归 如果应用程序使用递归——例如,计算斐波纳契数列——并且终端环境不正确,应用程序会运行很长一段时间后才用尽内存或超时。
您可以设定xdebug.max_nesting_level参数来限定递归深度。
例如,xdebug.max_nesting_level=50将把递归深度限定为50次嵌套调用,然后将强制终止应用程序。
下面演示一下,在启用Xdebug的状态下运行下列代码:
清单2.限制递归 functiondeep_end(){ deep_end(); } deep_end(); ?
> 函数deep_end()将逐行进行到最底部。
Xdebug将在49次函数调用后介入并得到图2(顺便说一句,main()的初始调用用于启动程序计数作为第1次调用)。
图2.如果调用堆栈超出限制,Xdebug将终止执行 如果应用程序大量使用递归隔离并解决较大的问题,则需要把深度相应地设定得“更低”。
否则,将xdebug.max_nesting_level设为较小的值,这样可以更快速地捕捉失控的函数调用序列。
回答四个w问题 出错时,您需要回答四个w问题。
Xdebug可以立即提供所有这些信息。
下面是一些有益的初始设置;您可以随时调整这些设置。
清单3.错误 xdebug.dump_once=On xdebug.dump_globals=On xdebug.dump_undefined=On xdebug.dump.SERVER=REQUEST_METHOD,REQUEST_URI,HTTP_USER_AGENT xdebug.dump.REQUEST=* xdebug.show_exception_trace=On xdebug.show_local_vars=1 xdebug.var_display_max_depth=6 xdebug.dump_once、xdebug.dump_globals、xdebug.dump_undefined和xdebug.dump_SUPERGLOBAL设置(其中SUPERGLOBAL可以是COOKIE、FILES、GET、POST、REQUEST、SERVER或SESSION)用于控制哪些PHP超全局变量将被包含在所有诊断结果中。
将xdebug.dump_globals设为On以转储名为xdebug.dump_SUPERGLOBAL设置中的超全局变量。
例如,xdebug.dump_SERVER=REQUEST_METHOD,REQUEST_URI,HTTP_USER_AGENT将打印PHP超全局变量$_SERVER['REQUEST_METHOD']、$_SERVER['REQUEST_URI']和$_SERVER['HTTP_USER_AGENT']。
如果需要打印超全局变量数组中的所有值,请使用星号(*),例如xdebug.dump_REQUEST=*。
如果进一步将xdebug.dump_undefined设为On并且不设定指定的超全局变量,则仍用值undefined打印变量。
即使捕捉到异常,代码行xdebug.show_exception_trace=On仍将强制执行异常跟踪。
代码行xdebug.show_local_vars=1将打印每个函数调用的最外围中的所有局部变量,包括尚未初始化的变量。
而xdebug.var_display_max_depth=6表示转储复杂变量的深度。
整合 清单4显示了php.ini文件的Xdebug的所有相关设置。
清单4.php.ini文件的设置 zend_extension=/usr/lib/php4/20020429/xdebug.so xdebug.default_enable=On xdebug.show_exception_trace=On xdebug.show_local_vars=1 xdebug.max_nesting_level=50 xdebug.var_display_max_depth=6 xdebug.dump_once=On xdebug.dump_globals=On xdebug.dump_undefined=On xdebug.dump.REQUEST=* xdebug.dump.SERVER=REQUEST_METHOD,REQUEST_URI,HTTP_USER_AGENT 将这些设置(或类似的内容)保存到php.ini文件中,然后重新启动Web服务器。
回页首解释转储报告 以下示例显示了出错时发生的情况。
把您的“有待改进”的代码修改为类似清单5所示的代码。
清单5.修改错误代码 functiondeep_end($count){ //addonetotheframecount $count+=1; if($count<48){ deep_end($count); } else{ trigger_error("goingoffthedeepend!
"); } } //main()iscalledtostarttheprogram, //sothecallstackbeginswithoneframe deep_end
(1); ?
> 如果运行这段新代码,您应当会看到大量信息,如下所示:
图3.出错时超全局变量、堆栈和局部变量的转储 传递给trigger_error的消息文本显示在顶部。
底部是受请求的$_SERVER元素列表和已经定义的$_REQUEST元素列表。
最底部是#48范围中的变量列表,这是根据清单对deep_end()进行的调用。
在调用中,$count是整数48。
当此Xdebug配置就绪后,您现在有更多的线索可以跟踪犯罪者。
下面是另外一个技巧:
Xdebug提供了一个增强型var_dump()函数,它对于PHP数组和类尤为有帮助。
例如,清单6显示了简单的(PHPV4)类和实例。
清单6.PHPV4类和实例 classPerson{ var$name; var$surname; var$age; var$children=array(); functionPerson($name,$surname,$age,$children=null){ $this->name=$name; $this->surname=$surname; $this->age=$age; foreach($childrenas$child){ $this->children[]=$child; } } } $boy=newPerson('Joe','Smith',4); $girl=newPerson('Jane','Smith',6); $mom=newPerson('Mary','Smith',34,array($boy,$girl)); var_dump($boy,$mom); ?
> 清单7显示了var_dump()的输出。
清单7.var_dump()输出 object(person) var'name'=>string'Joe'(length=3) var'surname'=>string'Smith'(length=5) var'age'=>int4 var'children'=> array empty object(person) var'name'=>string'Mary'(length=4) var'surname'=>string'Smith'(length=5) var'age'=>int34 var'children'=> array 0=> object(person) var'name'=>string'Joe'(length=3) var'surname'=>string'Smith'(length=5) var'age'=>int4 var'children'=> array empty 1=> object(person) var'name'=>string'Jane'(length=4) var'surname'=>string'Smith'(length=5) var'age'=>int6 var'children'=> array empty 如果结合使用Xdebug与PHPV5类,转储包括public、private和protected之类的属性。
回页首跟踪代码 解决错误——如解开神秘谋杀之谜——通常要求构造详细的时间线。
例如,内存泄漏通常不会把自身表明为一个错误计算。
相反,操作将正常进行,直至内存用尽,然后应用程序突然终止。
如果内存泄漏由于某些请求而恶化,可能会不断出现错误并且难以预测。
在内存使用量与时间之间建立映射的时间线将揭示泄漏的严重程度。
一条精细的时间线——比如,从函数到函数——将进一步指出泄漏源。
Xdebug可以提供一条详细的时间线进行执行跟踪。
当跟踪被启用后,Xdebug将记录所有函数调用,包括每个函数的参数和返回值。
您可以将每个日志或跟踪的格式设为符合人类阅读习惯或者机器可读的格式。
您最好使用前者,虽然您可能编写独立而特定的应用程序来分析后者。
同转储一样,Xdebug有若干个php.ini选项用于自定义跟踪内容。
例如,下面一批设置将生成最详细的输出。
清单8.跟踪自定义 xdebug.trace_format=0 xdebug.auto_trace=On xdebug.trace_output_dir=/tmp/traces xdebug.trace_output_name=trace.%c.%p xdebug.collect_params=4 xdebug.collect_includes=On xdebug.collect_return=On xdebug.show_mem_delta=On 设定xdebug.auto_trace=1将在执行所有PHP脚本之前先启用自动跟踪。
另外,您可以通过代码设定xdebug.auto_trace=0,并分别使用xdebug_start_trace()和xdebug_stop_trace()函数启用和禁用跟踪。
但是,如果xdebug.auto_trace为1,则可以在包括配置好的auto_prepend_file之前先启动跟踪。
选项xdebug.trace_ouput_dir和xdebug.trace_output_name用于控制保存跟踪输出的位置。
在这里,所有文件都被保存到/tmp/traces中,并且每个跟踪文件都以trace为开头,后接PHP脚本的名称(%s)以及进程ID(%p)。
所有Xdebug跟踪文件都以.xt后缀结尾。
默认情况下,Xdebug将显示时间、内存使用量、函数名和函数调用深度字段。
如果将xdebug.trace_format设为0,则输出将符合人类阅读习惯(将参数设为1则为机器可读格式)。
此外,如果指定xdebug.show_mem_delta=1,则可以查看内存使用量是在增加还是在减少,而如果指定xdebug.collect_params=4,则可以查看传入参数的类型和值。
要监视每个函数返回的值,请设定xdebug.collect_ret