如何调试PHP脚本?
我知道基本的调试,如使用错误报告。PHPEclipse中的断点调试也非常有用。
在phpStorm或任何其他IDE中调试的最佳方法(就快速和简单而言)是什么?
如何调试PHP脚本?
我知道基本的调试,如使用错误报告。PHPEclipse中的断点调试也非常有用。
在phpStorm或任何其他IDE中调试的最佳方法(就快速和简单而言)是什么?
当前回答
PHP DBG
交互式逐步PHP调试器实现为一个SAPI模块,它可以让你完全控制环境,而不影响代码的功能或性能。它的目标是成为一个轻量级、功能强大、易于使用的PHP 5.4+调试平台,它随PHP 5.6一起发布。
功能包括:
Stepthrough调试 灵活的断点(类方法,函数,文件:行,地址,操作码) 使用内置eval()轻松访问PHP 轻松访问当前正在执行的代码 用户态的API SAPI不可知论-易于集成 PHP配置文件支持 JIT超级全球赛-设置你自己!! 可选readline支持-舒适的终端操作 远程调试支持-绑定的Java GUI 操作简单
请看截图:
首页:http://phpdbg.com/
PHP错误-更好的PHP错误报告
这是非常容易使用库(实际上是一个文件)来调试PHP脚本。
你需要做的唯一一件事就是包括一个文件,如下所示(在你的代码的开头):
require('php_error.php');
\php_error\reportErrors();
然后所有的错误都会给你一些信息,比如回溯、代码上下文、函数参数、服务器变量等等。例如:
功能包括:
trivial to use, it's just one file errors displayed in the browser for normal and ajaxy requests AJAX requests are paused, allowing you to automatically re-run them makes errors as strict as possible (encourages code quality, and tends to improve performance) code snippets across the whole stack trace provides more information (such as full function signatures) fixes some error messages which are just plain wrong syntax highlighting looks pretty! customization manually turn it on and off run specific sections without error reporting ignore files allowing you to avoid highlighting code in your stack trace application files; these are prioritized when an error strikes!
首页:http://phperror.net/
GitHub: https://github.com/JosephLenton/PHP-Error
我的叉子(有额外的修复):https://github.com/kenorb-contrib/PHP-Error
DTrace
如果您的系统支持DTrace动态跟踪(在OS X上默认安装),并且您的PHP编译时启用了DTrace探测(——enable-dtrace),这应该是默认的,这个命令可以帮助您在没有时间的情况下调试PHP脚本:
sudo dtrace -qn 'php*:::function-entry { printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }'
因此,给定以下别名已添加到您的rc文件中(例如~/。bashrc, (~ / .bash_aliases):
alias trace-php='sudo dtrace -qn "php*:::function-entry { printf(\"%Y: PHP function-entry:\t%s%s%s() in %s:%d\n\", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }"'
您可以使用易于记忆的别名跟踪脚本:trace-php。
这里是更高级的dtrace脚本,只需将其保存到dtruss-php。D,使其可执行(chmod +x dtruss-php.d),并运行:
#!/usr/sbin/dtrace -Zs
# See: https://github.com/kenorb/dtruss-lamp/blob/master/dtruss-php.d
#pragma D option quiet
php*:::compile-file-entry
{
printf("%Y: PHP compile-file-entry:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1));
}
php*:::compile-file-return
{
printf("%Y: PHP compile-file-return:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), basename(copyinstr(arg1)));
}
php*:::error
{
printf("%Y: PHP error message:\t%s in %s:%d\n", walltimestamp, copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::exception-caught
{
printf("%Y: PHP exception-caught:\t%s\n", walltimestamp, copyinstr(arg0));
}
php*:::exception-thrown
{
printf("%Y: PHP exception-thrown:\t%s\n", walltimestamp, copyinstr(arg0));
}
php*:::execute-entry
{
printf("%Y: PHP execute-entry:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}
php*:::execute-return
{
printf("%Y: PHP execute-return:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}
php*:::function-entry
{
printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::function-return
{
printf("%Y: PHP function-return:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::request-shutdown
{
printf("%Y: PHP request-shutdown:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}
php*:::request-startup
{
printf("%Y, PHP request-startup:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}
主页:GitHub的dtruss-lamp
下面是简单的用法:
执行命令sudo dtruss-php.d。 在另一个终端运行:php -r "phpinfo();"。
为了测试这一点,你可以使用index.php找到任何docroot,并通过以下方式运行PHP内置服务器:
php -S localhost:8080
之后,您可以通过http://localhost:8080/访问该网站(或选择任何对您方便的端口)。从那里访问一些页面以查看跟踪输出。
注意:Dtrace默认在OS X上可用,在Linux上你可能需要dtrace4linux或检查一些其他替代方案。
参见:在php.net上使用PHP和DTrace
SystemTap
或者通过安装SystemTap SDT开发包来检查SystemTap跟踪(例如yum install SystemTap - SDT -devel)。
下面是一个示例脚本(all_probes.stp),用于在SystemTap运行的PHP脚本期间跟踪所有核心PHP静态探测点:
probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
printf("Probe compile__file__entry\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
printf("Probe compile__file__return\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("error") {
printf("Probe error\n");
printf(" errormsg %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
}
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
printf("Probe exception__caught\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
printf("Probe exception__thrown\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
printf("Probe execute__entry\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("execute__return") {
printf("Probe execute__return\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("function__entry") {
printf("Probe function__entry\n");
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("function__return") {
printf("Probe function__return: %s\n", user_string($arg1));
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
printf("Probe request__shutdown\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
probe process("sapi/cli/php").provider("php").mark("request__startup") {
printf("Probe request__startup\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
用法:
stap -c 'sapi/cli/php test.php' all_probes.stp
参见:在php.net上使用SystemTap和PHP DTrace静态探针
其他回答
我使用Netbeans的XDebug和Easy XDebug FireFox插件
The add-on is essential when you debug MVC projects, because the normal way XDebug runs in Netbeans is to register the dbug session via the url. With the add-on installed in FireFox, you would set your Netbeans project properties -> Run Configuratuion -> Advanced and select "Do Not Open Web Browser" You can now set your break points and start the debugging session with Ctrl-F5 as usual. Open FireFox and right-click the Add-on icon in the right bottom corner to start monitoring for breakpoints. When the code reaches the breakpoint it will stop and you can inspect your variable states and call-stack.
PHP DBG
交互式逐步PHP调试器实现为一个SAPI模块,它可以让你完全控制环境,而不影响代码的功能或性能。它的目标是成为一个轻量级、功能强大、易于使用的PHP 5.4+调试平台,它随PHP 5.6一起发布。
功能包括:
Stepthrough调试 灵活的断点(类方法,函数,文件:行,地址,操作码) 使用内置eval()轻松访问PHP 轻松访问当前正在执行的代码 用户态的API SAPI不可知论-易于集成 PHP配置文件支持 JIT超级全球赛-设置你自己!! 可选readline支持-舒适的终端操作 远程调试支持-绑定的Java GUI 操作简单
请看截图:
首页:http://phpdbg.com/
PHP错误-更好的PHP错误报告
这是非常容易使用库(实际上是一个文件)来调试PHP脚本。
你需要做的唯一一件事就是包括一个文件,如下所示(在你的代码的开头):
require('php_error.php');
\php_error\reportErrors();
然后所有的错误都会给你一些信息,比如回溯、代码上下文、函数参数、服务器变量等等。例如:
功能包括:
trivial to use, it's just one file errors displayed in the browser for normal and ajaxy requests AJAX requests are paused, allowing you to automatically re-run them makes errors as strict as possible (encourages code quality, and tends to improve performance) code snippets across the whole stack trace provides more information (such as full function signatures) fixes some error messages which are just plain wrong syntax highlighting looks pretty! customization manually turn it on and off run specific sections without error reporting ignore files allowing you to avoid highlighting code in your stack trace application files; these are prioritized when an error strikes!
首页:http://phperror.net/
GitHub: https://github.com/JosephLenton/PHP-Error
我的叉子(有额外的修复):https://github.com/kenorb-contrib/PHP-Error
DTrace
如果您的系统支持DTrace动态跟踪(在OS X上默认安装),并且您的PHP编译时启用了DTrace探测(——enable-dtrace),这应该是默认的,这个命令可以帮助您在没有时间的情况下调试PHP脚本:
sudo dtrace -qn 'php*:::function-entry { printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }'
因此,给定以下别名已添加到您的rc文件中(例如~/。bashrc, (~ / .bash_aliases):
alias trace-php='sudo dtrace -qn "php*:::function-entry { printf(\"%Y: PHP function-entry:\t%s%s%s() in %s:%d\n\", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }"'
您可以使用易于记忆的别名跟踪脚本:trace-php。
这里是更高级的dtrace脚本,只需将其保存到dtruss-php。D,使其可执行(chmod +x dtruss-php.d),并运行:
#!/usr/sbin/dtrace -Zs
# See: https://github.com/kenorb/dtruss-lamp/blob/master/dtruss-php.d
#pragma D option quiet
php*:::compile-file-entry
{
printf("%Y: PHP compile-file-entry:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1));
}
php*:::compile-file-return
{
printf("%Y: PHP compile-file-return:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), basename(copyinstr(arg1)));
}
php*:::error
{
printf("%Y: PHP error message:\t%s in %s:%d\n", walltimestamp, copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::exception-caught
{
printf("%Y: PHP exception-caught:\t%s\n", walltimestamp, copyinstr(arg0));
}
php*:::exception-thrown
{
printf("%Y: PHP exception-thrown:\t%s\n", walltimestamp, copyinstr(arg0));
}
php*:::execute-entry
{
printf("%Y: PHP execute-entry:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}
php*:::execute-return
{
printf("%Y: PHP execute-return:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}
php*:::function-entry
{
printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::function-return
{
printf("%Y: PHP function-return:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::request-shutdown
{
printf("%Y: PHP request-shutdown:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}
php*:::request-startup
{
printf("%Y, PHP request-startup:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}
主页:GitHub的dtruss-lamp
下面是简单的用法:
执行命令sudo dtruss-php.d。 在另一个终端运行:php -r "phpinfo();"。
为了测试这一点,你可以使用index.php找到任何docroot,并通过以下方式运行PHP内置服务器:
php -S localhost:8080
之后,您可以通过http://localhost:8080/访问该网站(或选择任何对您方便的端口)。从那里访问一些页面以查看跟踪输出。
注意:Dtrace默认在OS X上可用,在Linux上你可能需要dtrace4linux或检查一些其他替代方案。
参见:在php.net上使用PHP和DTrace
SystemTap
或者通过安装SystemTap SDT开发包来检查SystemTap跟踪(例如yum install SystemTap - SDT -devel)。
下面是一个示例脚本(all_probes.stp),用于在SystemTap运行的PHP脚本期间跟踪所有核心PHP静态探测点:
probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
printf("Probe compile__file__entry\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
printf("Probe compile__file__return\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("error") {
printf("Probe error\n");
printf(" errormsg %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
}
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
printf("Probe exception__caught\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
printf("Probe exception__thrown\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
printf("Probe execute__entry\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("execute__return") {
printf("Probe execute__return\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("function__entry") {
printf("Probe function__entry\n");
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("function__return") {
printf("Probe function__return: %s\n", user_string($arg1));
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
printf("Probe request__shutdown\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
probe process("sapi/cli/php").provider("php").mark("request__startup") {
printf("Probe request__startup\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
用法:
stap -c 'sapi/cli/php test.php' all_probes.stp
参见:在php.net上使用SystemTap和PHP DTrace静态探针
PhpEd真的很好。你可以进入/进入/退出函数。你可以运行特别代码,检查变量,改变变量。太神奇了。
Nusphere也是一个很好的php调试器 nusphere
手动调试对我来说通常更快——var_dump()和debug_print_backtrace()是你需要用来武装你的逻辑的所有工具。