如何为 PhpStorm 设计注释从不返回控制权的 PHP 函数/方法

Sma*_*min 6 php phpstorm

有时,有必要/方便地引入从不返回控制权的 PHP 函数或方法 - 也就是说,总是调用 exit() 或引发异常。例如,我们需要一些共享代码,它将给定的异常实例转换为其他类的异常实例并重新抛出它 - 但永远不会将控制权返回给调用者。

如何注释这些函数/方法,特别是对于 PhpStorm?它不仅仅是 @return void ,它还应该提示控件永远不会返回,因此 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!!!
}

Run Code Online (Sandbox Code Playgroud)

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

kem*_*emp 8

好消息!neverPHP 8.1 中出现返回类型

这是一些示例代码:

public function redirectToHomePage() : never
{
    header('Location: /home');
    exit();
}
Run Code Online (Sandbox Code Playgroud)

您可以从 RFC 中了解更多信息:


hak*_*kre 4

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

\n
/**\n * @return no-return\n */\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
\n

更规范的答案是:

\n
/**\n * @return never\n */\n
Run Code Online (Sandbox Code Playgroud)\n

答案更加规范,因为never [DOC] [ RFC ]是从 PHP 8.1 开始的语言关键字,用于其底层类型[WP] - 从不返回函数的返回类型。

\n\n

但截至目前,PHPStorm 对此变体的支持有限。您发现它确实符合您的要求(检测无法访问的语句),但仍然存在误报,将 PHPDoc 注释标记为与实际返回类型不匹配。

\n

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

\n
\n

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

\n
/**\n * @return never\n * @return never-return\n * @return never-returns\n * @return no-return\n */\n
Run Code Online (Sandbox Code Playgroud)\n

为何有如此多的选择?一种有根据的猜测是,现在在Matt Brown和Ond\xc5\x99ej Mirtesnever (PHP 静态分析工具 Psalm 和 Phpstan 的作者)的倡议下进入 PHP 8.1,并且这两个项目在过去已经简化了注释,这就是列表结果出来了(如果你真的想捕获所有这些,请添加到列表中,因为它之前是根据 RFC 建议的,但没有成功,获胜者将获得全部)。noreturnnever

\n

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

\n

现在已经给出了一个(或三个半)答案,接下来是这个答案\'

\n
\n
\n

PHP 了解您的语言测验

\n
\n
\n

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

\n

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

\n
class no-return \n{\n}\n
Run Code Online (Sandbox Code Playgroud)\n

进入 PHP 源代码,对吗?(如果不是tableflip,那就是语法错误。)所以无论如何没有人会使用这样的类名。

\n

但仍然存在一个问题:no-return类名是否有效?您可以在 PHP 中实例化对象、调用方法等吗?

\n
\n

在 PHP 语言级别上有一个警告:no-return是自 PHP 5.3 以来完全有效的 PHP 类名,当时class_alias()引入该函数是为了为库提供切换到命名空间的选项,但要保持向后兼容性。

\n
\n
\n

从那时起,PHP 中允许使用此类名称 - 但仅限于用户空间中的别名。如果你更深入地了解,“理论上,由于奇怪的(第 3 方)扩展等,具有此类名称的类可能存在。” 。[参考]

\n
\n