PHP 调试 - 如何调试 PHP 代码(包括 Drupal 调试技术!)

已发表: 2019-09-03

调试不是我们开发人员所期待的。 开发人员厌恶错误,但为了能够构建出优质的软件,调试是开发人员生活中不可或缺的一部分。 每个 PHP 开发人员都有不同的风格和调试代码的首选方法。 这取决于他们的经验、解决问题的方法以及最重要的 - 他们手头的时间!

调试有多重要,为什么需要调试代码?

调试是确保质量结果的软件开发生命周期的一个组成部分。
想象一下 - 代码库很大,您是项目的新手,您没有太多关于项目/功能的细节。 但是你应该修复一个错误。 我们从哪里开始? 我们从逐步分析代码开始,以了解做了什么以及哪里出错了。 我的朋友们,这就是调试。 调试是一门艺术,可以通过实践和经验变得更好。

如何调试你的 PHP 代码

好的,这是我在开发生涯中遇到的一个案例。 有一个建立在 Wordpress 上的商业网站,其中结帐过程大约需要 5-8 分钟,我被要求解决它。 在这种情况下,我对 Wordpress 的工作原理知之甚少。 所以我开始从列表中一一勾选选项,例如,(a) 是不是因为某个插件? (b) 与主题有关吗? (c) 是否有任何自定义代码库? 等等。

帮助我进行 php 调试和解决此案例的工具是 Blackfire。 这为所有函数的堆栈跟踪提供了一个更具用户可读性的选项,即整个过程中每个函数所花费的时间。 通过使用它,我发现了消耗结帐过程的功能。 您只需要进行一些设置即可将密钥添加到您的代码库中,并且您已经准备好使用文档分析任何功能。
因此,如果您了解多种 php 调试方法,则可以解决这些错误。

代码调试技巧

让我谈谈我用于调试 PHP 的一些技术。
检查您编写的函数或方法是否被调用的一种简单且最常见的方法是编写退出。 没有任何开发人员没有使用过它!
要检查某个变量的值,print_r()、var_dump()、var_export()。 好的,让我们看看区别。

例子:

 假设一个数组 
$a = array( 1, array( "a", "b") );
打印_r($a);

 
大批
(
[ 0 ] => 1
[ 1 ] =>数组
(
[ 0 ] => 'a'
[ 1 ] => 'b'
)
)

这提供了人类可读的格式和有关变量的信息。 此外,我们可以使用 print_r($var, true) 将其存储到变量中。

 var_dump( $a );
 数组( 3 ) {
[ 0 ]=>
整数( 1 )
[ 1 ]=>
  数组( 2 ) {
[ 0 ]=>
字符串( 1 ) "a"
[ 1 ]=>
字符串( 1 ) "b"
}
}

这将打印每个值的类型、长度。 这比 print_r() 更快
var_export( $a );

 数组(
  0 => 1 ,
  1 =>
  数组(
    0 => 'a' ,
    1 => 'b' ,
),
)

这将打印每个值的类型、长度。 这比 print_r() 更快
var_export( $a );

如果变量存在,则返回有效的 php,否则返回 false。 这意味着 var_export 的输出可以直接在 php 文件中使用。

你有没有使用过 Drupal 核心提供的debug($var, NULL, TRUE) ? 这根据传递给 php 调试函数的参数使用 print_r() 或 var_export。

像下面这样的警告怎么样,你不知道哪一行代码导致了这样的警告。

警告:为第485行 /modules/node/node.module 中的 foreach() 提供的参数无效。

我们知道有很多地方会调用node模块。 那么,你如何解决这个问题? 一种不使用任何其他外部资源的更快方法是使用 PHP 函数debug_backtrace() 。 转到“drupal_set_message”,因为你知道,这是打印警告的方法。 把下面的行,在那个函数中

debug_backtrace();

输出:

大批
(
[ 0 ] =>数组
(
[文件] => /includes/common.inc
[行] => 552
[功能] => drupal_set_message
[参数] =>数组
(
[ 0 ] => 警告:无效

为 foreach() 提供的参数

/modules/node/node.module 在第504
[ 1 ] => 错误
)

)

[1] =>数组
(
[文件] => /modules/node/node.module
[行] => 504
[功能] => error_handler
[参数] => 数组
(
[ 0 ] => 2
[ 1 ] => 无效参数
为 foreach() 提供
[ 2 ] => /模块/节点/
节点模块
[ 3 ] => 504
[ 4 ] => 数组
(
[参数] =>
[修订] =>
[重置] =>
...
)

)

)

[2] =>数组
(
[文件] => /sites/all/modules/custom/custom_module
/custom_module.module
[行] => 10
[功能] => node_load
[参数] => 数组
(
[ 0 ] =>
)

)

[3] =>数组
(
[文件] => /includes/form.inc
[行] => 365
[功能] => custom_module_form_alter
[参数] => 数组
(
...

该函数显示了在导致警告的过程中调用的所有函数的堆栈。 确保限制限制,否则如果堆栈显示时间过长,PHP 会显示“内存耗尽”消息。

通过 CLI 调试:

听说过phpdbg ! 是的,PHP 5.6+ 提供了一个 php 扩展,用于从命令行调试 php 文件。
打开终端,输入“phpdbg”。 这将启动一个交互式 php 调试器外壳。 您也可以使用断点! 试试吧 - 调试 PHP 的隐藏方式。
唯一的问题是:您必须习惯 phpdbg 的命令才能更好地使用它。

通过 Drupal 调试:

Devel Kint: Drupal 开发人员经常使用它。 Kint 是 Devel 模块的一个子模块,可用于与 dump() 一起调试 Drupal 8 twig 模板;

数据库日志:谁不知道这个 Drupal 模块?! 在 D7 中它是watchdog(),而 D8 中它是记录器服务。

\Drupal::logger( 'my_module' )->debug($message);

但是我们不鼓励使用这个模块的唯一原因,即使我们喜欢它,也是每次都会将日志消息写入数据库!

并且想象一下,如果它是一个巨大的数据库,这会更糟并且会影响性​​能。 这就是原因,不建议在生产站点上使用 DBLOG 模块。
您是否还想使用 DBLog、模块并降低性能影响? 也有一个解决方案 - Dlog 过滤器。 这是一个贡献模块,有助于限制写入数据库的日志类型。 例如,如果您只想存储严重性为“错误”的日志,则可以使用此模块对其进行配置。 所以你不必完全摆脱Dblog模块。 哦,是的,这个模块是我贡献的 ;)

网页分析器

Web profiler 是 Devel 再次提供的一个贡献模块。 启用模块后,您将在窗口底部看到一个报告。 每当加载页面时,此报告都会为我们提供页面加载时间、页面中运行的查询数量、表单数量、该页面中的 js/css 文件数量等。

网络分析器

是的,这甚至可以通过单击来提供每个部分的详细信息。 例如,下图显示了主页中的查询。

调试

XDebug - 通过 IDE 调试:

如果使用 IDE 进行编码,大多数人更喜欢的最佳且更用户友好的调试方式是使用 XDebug。 XDebug 是一个有助于开发和调试的 PHP 扩展,并提供了一个单步调试器,您可以将它与像 PHPStorm 这样的 IDE 一起使用。 当然,为了获得最佳结果,您必须付出更多努力来使用您正在使用的 IDE 安装和配置扩展。