2.9. 故障诊断类型
故障诊断类型
PHPStan有时可以将表达式解析为你意想不到的类型。本指南旨在帮助你诊断这些类型可能来自哪里。以下是 PHPStan 获取类型信息的所有位置列表。
原生类型
PHPStan 使用原生参数类型、返回类型和属性(property)类型去告知关于类型的分析。
private int $prop;
function foo(Foo $foo): Bar
{
// ...
}
PHPDoc 类型
PHPDoc 的 @param
和 @return
以及其他 标记可以传递和原生表达同样的类型,并在 PHP 运行时进行检查(例如 int
或者 object
),也包括只在被静态分析器检查时才有意义的 其他类型 。
这些类型与原生类型一起被解释,也可以把两者组合起来:
/** @param array<int, Item> $items */
function foo(array $items)
{
}
存根文件
除了被分析的源码,PHPStan 也会利用所谓的用于覆盖错误的第三方 PHPDocs 的 存根文件。这些存根文件可以来自 PHPStan 拓展,也可以直接自己编写。
内部存根
PHPStan 需要知道内置 PHP 函数的精确参数和返回类型,以及那些已加载的PHP扩展的函数。有三个独立的来源:
- PHPStan 维护的
functionMap.php
,和不同 PHP 版本的 deltas - jetbrains/phpstorm-stubs
- 如果你使用 PHP 8 或者更高版本,提取自 php-src 的 官方存根。
这些组合在一起去提供一个全貌非常复杂的逻辑,并随着 bug 得到修复和改进,经常发生变化。
局部类型缩小
在一个函数体内有很多种方式去局部缩小一个类型。本指南 有谈及。
这包括自定义的的 特定类型 拓展 和 内置的 PHPDoc @var
标签.
动态返回类型扩展
有很多 动态返回类型拓展 是为 PHP 内置函数注册的。它们可能来自 PHPStan 拓展,也可能来自你自己的项目配置。
调试
你可以在代码里使用 PHPStan\dumpType()
函数去检查 PHPStan 会把一个表达式解析成什么类型:
\PHPStan\dumpType(1 + 1); // Reports: Dumped type: 2
在使用了这个函数的代码上再次运行 PHPStan 以查看结果。
当然这个函数不应该在生成环境运行,因此不要忘记删除它!
PHPStan 不会做的事
PHPStan 不会进入被调用的函数体去查看细节。原生类型、PHPDocs、还有注册的 动态返回类型 和 特定类型 拓展 是它理解类型将受到的所有影响。