如何注释 PHP function/method 从来没有 returns 为 PhpStorm 设计控制

How to annotate PHP function/method which never returns control by design for PhpStorm

偶尔,necessary/convenient 引入从未 return 控制的 PHP 函数或方法 - 也就是说,总是调用 exit() 或抛出异常。例如。我们需要一些共享代码,将给定的异常实例转换为其他 class 的异常实例并重新抛出它 - 但永远不会 return 将控制权交给调用者。

如何注释这样的 functions/methods,尤其是对于 PhpStorm?它不仅仅是 @return void ,它应该提示控件永远不会 returns,因此 IDE 正确警告调用后出现的死代码。

/** @how-to-annotate-return? */
function outputAndExit($message) {
  echo $message . "\nExiting\n";
  exit();
}

/** @how-to-annotate-return? */
function convertException(\Exception $e) {
  throw $e instance \LogicException ? new \RuntimeException : $e;
}

// ... so that following code will generate dead code warning:
try {
 // some code which may throw exception
 $m = 'happy';
 outputAndExit($m);
 $m = 'sad'; // dead code!!!
} catch (\Exception $e) {
 convertException($e);
 logger('Error happened'); // dead code!!!
}

IDE 应该将注释行标记为“// 死代码!!!”作为死代码。

好消息! never return 类型即将在 PHP 8.1

中推出

下面是一些示例代码:

public function redirectToHomePage() : never
{
    header('Location: /home');
    exit();
}

你可以了解更多from the RFC:

这还需要一个答案(对于Docblock注释),它是:

/**
 * @return no-return
 */

自 2020.3 起支持 PHPStorm(2020 年 12 月 3 日,在 EAP 2 之前,请参阅 WI-55898)。


比较规范的答案是:

/**
 * @return never
 */

never [DOC] [RFC] is the language keyword from PHP 8.1 onwards for its bottom type [WP] - return 类型的永不 return 函数的意义上说,答案更规范。

  • 比较:

但截至今天,PHPStorm 中对该变体的支持是有限的。您发现它对您的要求有效(检测无法访问的语句),但仍然存在标记 PHPDoc 注释与实际 return 类型不匹配的误报。

当工具允许我们时,我们会谦虚地选择第一个答案和规范。其他工具已经很好用了,也许下一个 Phpstorm 版本也可以。


一般答案是以下任何一个:

/**
 * @return never
 * @return never-return
 * @return never-returns
 * @return no-return
 */

为什么会有这么多选择?一种有根据的猜测是,现在 neverMatt BrownOndřej Mirtes 的倡议下进入 PHP 8.1( PHP 静态分析工具 Psalm 和 Phpstan 的作者)并且这两个项目在过去都已经简化了注释这就是列表的结果(如果你真的想抓住它们,添加 noreturn 到根据 RFC 之前建议的列表,但没有成功,获胜者是 never 并获得全部)。

谦虚地我们自己发现 @return no-return 在 Phpstorm 中工作,而之前已经完美地使用了 @psalm-return no-return。我们可以想象 Phpstan 也是如此。

既然已经给出了一个(或三个半)答案,下面是这个答案'


PHP Know-Your-Language Quiz


Phpstorm(以及其他静态分析器,如 Psalm 或 PHPStan)可以通过暗示 no-return 不是有效的 PHP class 名称来走捷径。

这在静态代码分析的层面上通常应该是完美的,因为你不能把

class no-return 
{
}

进入 PHP 源代码,right? (It's a syntax error if not tableflip。)所以无论如何没人会使用这样的 class 名称。

但问题仍然存在:no-return 是有效的 class 名称吗?您可以在 PHP?

中实例化对象、调用方法等

在 PHP 语言级别有一个警告:no-return 是一个完全有效的 PHP class 名称,因为 PHP 5.3 当 class_alias() function has been introduced to provide libraries with the option to switch to namespaces,但要保持向后兼容性。

从那时起,这样的 class 名称在 PHP 中是允许的 - 但仅限于用户空间中的别名。如果你更深入,"classes [with] 理论上 - 由于奇怪的(第 3 方)扩展等而存在 [REF]