作为 SAPI 模块实现的交互式分步 PHP 调试器可让您完全控制环境,而不会影响代码的功能或性能。它旨在成为 PHP 5.4+ 的轻量级、功能强大、易于使用的调试平台,并且随 PHP 5.6 一起提供。
功能包括:
- 逐步调试
- 灵活的断点(类方法、函数、文件:行、地址、操作码)
- 使用内置 eval() 轻松访问 PHP
- 轻松访问当前正在执行的代码
- 用户区 API
- 与 SAPI 无关 - 轻松集成
- PHP 配置文件支持
- JIT Super Globals - 设置你自己的!!
- 可选的 readline 支持 - 舒适的终端操作
- 远程调试支持 - 捆绑的 Java GUI
- 操作简单
查看截图:
首页:http://phpdbg.com/
这是一个非常易于使用的库(实际上是一个文件)来调试您的 PHP 脚本。
您唯一需要做的就是包含一个如下文件(在代码的开头):
require('php_error.php');
\php_error\reportErrors();
然后所有的错误都会给你回溯、代码上下文、函数参数、服务器变量等信息。例如:
功能包括:
- 简单易用,只有一个文件
- 正常和 ajaxy 请求在浏览器中显示的错误
- AJAX 请求已暂停,您可以自动重新运行它们
- 使错误尽可能严格(提高代码质量,并倾向于提高性能)
- 在整个堆栈跟踪中编写 sn-ps 代码
- 提供更多信息(例如完整的函数签名)
- 修复了一些完全错误的错误消息
- 语法高亮
- 看起来很漂亮!
- 定制
- 手动开启和关闭
- 运行特定部分而不报告错误
- 忽略文件,让您避免在堆栈跟踪中突出显示代码
- 应用程序文件;发生错误时优先处理这些内容!
首页:http://phperror.net/
GitHub:https://github.com/JosephLenton/PHP-Error
我的叉子(有额外的修复):https://github.com/kenorb-contrib/PHP-Error
如果您的系统支持DTrace dynamic tracing(默认安装在 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));
}
主页:dtruss-lamp 在 GitHub
这里是简单的用法:
- 运行:
sudo dtruss-php.d。
- 在另一个终端上运行:
php -r "phpinfo();"。
要对此进行测试,您可以使用index.php 访问任何文档根目录并通过以下方式运行 PHP 内置服务器:
php -S localhost:8080
之后,您可以通过http://localhost:8080/ 访问该站点(或选择您方便的任何端口)。从那里访问一些页面以查看跟踪输出。
注意:Dtrace 默认在 OS X 上可用,在 Linux 上您可能需要 dtrace4linux 或检查其他一些 alternatives。
请参阅:Using PHP and DTrace at php.net
或者通过安装 SystemTap SDT 开发包(例如yum install systemtap-sdt-devel)来检查 SystemTap 跟踪。
这里是示例脚本 (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
请参阅:Using SystemTap with PHP DTrace Static Probes php.net