如何调试PHP脚本?

我知道基本的调试,如使用错误报告。PHPEclipse中的断点调试也非常有用。

在phpStorm或任何其他IDE中调试的最佳方法(就快速和简单而言)是什么?


当前回答

通过简单地var_dump一些关键变量,可以很容易地找到大多数错误,但这显然取决于您开发的应用程序类型。

对于更复杂的算法,步进/断点/观察函数是非常有用的(如果没有必要)

其他回答

您可以使用Firephp作为firebug的附加组件在与javascript相同的环境中调试php。

我还使用前面提到的Xdebug来分析php。

Komodo IDE works well with xdebug, even for the remore debugging. It needs minimum amount of configuration. All you need is a version of php that Komodo can use locally to step through the code on a breakpoint. If you have the script imported into komodo project, then you can set breakpoints with a mouse-click just how you would set it inside eclipse for debugging a java program. Remote debugging is obviously more tricky to get it to work correctly ( you might have to map the remote url with a php script in your workspace ) than a local debugging setup which is pretty easy to configure if you are on a MAC or a linux desktop.

Nusphere也是一个很好的php调试器 nusphere

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静态探针

XDebug对于开发至关重要。我安装它之前任何其他扩展。它为您提供任何错误的堆栈跟踪,您可以轻松地启用分析。

使用var_dump()可以快速查看数据结构。不要使用print_r(),因为你必须用<pre>包围它,而且它一次只打印一个var。

<?php var_dump(__FILE__, __LINE__, $_REQUEST); ?>

对于一个真正的调试环境,我发现最好的是Komodo IDE,但它要花费$$。