对于我正在编写的库,我希望能够模拟
exit
PHP 函数。
我尝试使用 php-mock 提供
exit
的命名空间版本,类似
namespace MyNamespace;
function exit()
{
// my mocked version of the function
}
但这会给解析器带来问题,抛出以下
ParseError
:syntax error, unexpected 'exit' (T_EXIT), expecting '('
。
是否有其他方法可以模拟内置函数而不引发解析问题?我应该尝试用 BetterReflection 之类的东西修改 AST 吗?
根据评论,我认为模拟语言构造是不可行的。
为了测试
exit()
,我最终使用 exec
生成其他进程,并断言它们的输出和存在状态
从 PHP 8.1 开始,引入了 Fiber,我正在起草一个想法,使用它们来中断执行并在中断后进行处理,而不终止 PHP 进程。
我的想法是将逻辑包装在 Fiber 中,如下所示:
<?php
function run(callable $operation): mixed
{
$fiber = new \Fiber($operation);
$suspended = $fiber->start();
if ($suspended instanceof ExitException) {
return $suspended;
}
return $fiber->getReturn();
}
function mockedExit(): void {
\Fiber::suspend(new ExitException('exit'));
}
$response = run(static function () {
// Some Logic
if (true) {
mockedExit();
}
// Continue Logic
return 'SUCCESS';
});
if ($response === 'SUCCESS') {
echo 200;
} else {
echo 500;
}
class ExitException extends \Exception {}
我在这里建议的是使用 Fibers 暂停执行,因为它们支持全栈功能。我可以预见一些权衡,例如管理嵌套 Fiber 的复杂性,但我没有看到任何直接的担忧。