cyber-duck / fluent-debug
This package is auto-updated.
Last update: 2023-09-08 11:20:56 UTC
README
此包将不再得到支持。
Fluent / 连接方法/函数 xDebug 库
## 为什么?
像 Laravel 这样的框架大量使用并鼓励方法连接。
考虑以下从 Laravel 框架中随机选取的一行代码
Finder::create()
->files()
->name('*.php')
->in($configPath)
这看起来很漂亮。但有个问题。假设我对
Finder::create()
->files()
->name('*.php')
的返回值感兴趣,并希望用调试器检查它。
目前,我所知道的在 PHP 中使用 xDebug 来完成这个操作的唯一方法是逐行执行,或者费时费力地重写代码以引入中间变量,即把上面的代码重写为
$a = Finder::create()
->files()
->name('*.php')
//put breakpoint on this line:
$a->in($configPath)
在这个例子中,这听起来并不特别困难,但很快就会变得一团糟。
让我们再考虑另一行随机代码
Chicken::load(meatProcess($sausage->bacon()));
假设我对这里的 $sausage->bacon()
的返回值感兴趣。我该在哪里设置断点来获取它?如果我把断点放在这行上,我就必须逐行执行对 bacon
的调用并截获返回值,这有时相当困难。或者,也许我可以把断点放在 meatProcess
调用的第一行上。第三种选择是做类似这样的事情
Chicken::load(meatProcess(($a = $sausage->bacon())->ketchup()));
$a;
然后在第二行上设置断点。但如果对 ketchup
的调用改变了 $a
?你就会被误导!
无论如何,我再次弄乱了代码。
这类事情是为什么有些程序员总的来说反对方法连接——调试确实变得困难得多。
例如,参见 https://ocramius.github.io/blog/fluent-interfaces-are-evil/
但我们在现实世界中生活,这是一种流行的方法,如果做得好,就像 Laravel 一样,会使你的代码更容易阅读。
## 如何?
所以,这里我提出一个非常简单的扩展,我相信它消除了大多数由流畅方法连接引起的调试痛苦。
扩展分为两部分。首先是一个具有两个方法的 trait,即 debugBreak
和 debugBreakIf
。这些方法实际上是 xdebug 安装的 xdebug_break
函数的包装。
使用方法如下
Finder::create()
->files()
->name('*.php')
->debugBreak()
->in($configPath)
或者也许
Finder::create()
->files()
->name('*.php')
->debugBreakIf(2 === $a)
->in($configPath)
或者确实
Finder::create()
->files()
->name('*.php')
->debugBreakIf(function(){return app()->isRunningUnitTests();))
->in($configPath)
要使用此功能,请将 use CyberDuck\Traits\DebugsFluently
添加到任何你希望使用它(或其父类)的类中。在我的不断增长的待办事项列表中,有一个计划是自动将此添加到每个类中。
其次——主要用于函数链——是全局函数 debugBreak
和 debugBreakIf
。
上面的例子将变为
Chicken::load(meatProcess(debugBreak($sausage->bacon())->ketchup()));
或者有 debugBreakIf
- 第二个参数的作用方式与 trait 中的 debugBreakIf
方法相同。
### 脚注
1: 有一种在 .NET 中完成此操作的方法——参见 https://davefancher.com/2016/01/28/functional-c-debugging-method-chains/