PHPStan 错误解析:phpstan.dumpNativeType——仅看原生类型,不看 PHPDoc 的调试利器
【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址: https://gitcode.com/gh_mirrors/ph/phpstan
\PHPStan\dumpNativeType()是 PHPStan 内置的调试函数:它会把某个表达式在 PHPStan 眼中的原生类型(native type,即 PHP 代码本身声明的类型)直接打印到分析输出中,且完全忽略 PHPDoc 注解。下面介绍它的触发机制、与dumpType()的区别,以及如何在日常排查中使用和清理它。
本文基于当前仓库 website/errors/phpstan.dumpNativeType.md 展开,并结合仓库中 phpstan.dumpType.md 等文档对比说明。
它什么时候被报告?
任何对\PHPStan\dumpNativeType()的调用都会触发一个phpstan.dumpNativeType错误。它刻意被实现为“错误”,因为调试类型信息的唯一目的就是让类型出现在分析输出里——如果它不报错,你就看不到任何东西。
官方给出的最小复现示例:
<?php declare(strict_types = 1); \PHPStan\dumpNativeType(1 + 1);运行vendor/bin/phpstan analyse时,输出中会出现类似:
Line file.php ------ -------------------- 3 Dumped type: int它与dumpType()有什么区别?
PHPStan 提供两个调试函数,二者的差别只在一个词:PHPDoc。
| 函数 | 关注点 | 典型场景 |
|---|---|---|
\PHPStan\dumpType($expr) | 推断出的完整类型,包含 PHPDoc 注解带来的信息(泛型、数组 shape、@param声明的精确类型等) | 查看 PHPStan 最终推断出的类型,包含文档注解 |
\PHPStan\dumpNativeType($expr) | 仅原生类型(native type),忽略 PHPDoc | 排查 PHPDoc 与真实代码类型是否不一致 |
dumpNativeType()的行为与dumpType()相同,但只考虑 PHP 原生类型信息。仓库文档中 phpstan.dumpType.md 描述了对应的场景,例如:
function doFoo(int $a, string $b): void { \PHPStan\dumpType($a); // Dumped type: int \PHPStan\dumpType($b); // Dumped type: string }- 如果你写的是
@param array<int, string> $list,那么dumpType($list)会输出array<int, string>; - 而
dumpNativeType($list)只会输出array,因为代码里只声明了array,泛型信息全部来自 PHPDoc。
这正是“原生类型”一词的含义:它只反映 PHP 代码本身(参数类型、返回类型、属性类型、字面量运算等)能表达的类型,PHPDoc 中的一切增强都会被忽略。
为什么会有这个函数?
在实际开发中,PHP 原生类型(int、string、array、?Foo等)往往不够精确,开发者会借助 PHPDoc(@param、@return、泛型、数组 shape 等)补充类型信息。当分析结果与预期不符时,你往往需要回答两个问题:
- PHPStan 最终认为这个表达式是什么类型?(用
dumpType()) - PHPStan 从纯代码中能看出什么类型?PHPDoc 是不是在“掩盖”某些问题?(用
dumpNativeType())
如果 PHPDoc 声称的类型与原生类型差异巨大,往往意味着注解过时或代码本身有问题。dumpNativeType()帮你把“PHP 自己表达的类型”单独拎出来观察。
如何修复?
修复方式只有一个:用完即删。它只是临时调试工具,分析完类型信息后把调用移除即可:
-\PHPStan\dumpNativeType(1 + 1); +// 恢复你的实际代码之所以必须删除,而不是通过 ignoreErrors 忽略,是因为:
- 该错误标识
ignorable: false(见 phpstan.dumpNativeType.md 的 front matter),不能忽略; - 它的存在本身就是提醒:调试代码不应该留在生产代码库里。
如果暂时不想删除又想跳过它,PHPStan 也允许使用--ignore-errors之类的命令行选项临时处理,但官方建议是直接删除调用。
实际排查示例
假设你有一段代码,想知道$value在当前代码位置的原生类型:
<?php declare(strict_types = 1); /** @param array<string, int> $map */ function doFoo(array $map): void { $value = $map['key'] ?? 0; \PHPStan\dumpNativeType($value); \PHPStan\dumpType($value); }dumpNativeType($value)可能输出int(因为?? 0保证非 null,且原生返回类型是int);dumpType($value)可能会输出int(同样来自?? 0的窄化),但如果$map的 PHPDoc 指定了更精确的类型,dumpType会展示 PHPDoc 带来的信息。
通过对比两个输出,你可以快速判断:某个类型到底是“PHP 原生类型”决定的,还是“PHPDoc 注解”补充的,从而定位分析结果异常的来源。
补充:何时用哪个?
| 你的疑问 | 使用函数 |
|---|---|
| PHPStan 对这个表达式最终推断成什么类型? | \PHPStan\dumpType() |
| 这段代码没写 PHPDoc 时会被推断成什么类型? | \PHPStan\dumpNativeType() |
| PHPDoc 写错了,导致分析结果异常? | 先用dumpNativeType()看原生类型,再用dumpType()对比 |
两个函数都要求 PHPStan 在运行时能解析\PHPStan\命名空间下的函数——由于它们是 PHPStan 内置的调试工具,只要你的项目通过 Composer 安装了 PHPStan,函数即可直接使用,无需额外配置。
总结
phpstan.dumpNativeType错误是 PHPStan 内置调试函数\PHPStan\dumpNativeType()被调用时产生的输出,它刻意作为错误上报,以便类型信息出现在分析结果中;- 它只输出表达式的原生 PHP 类型,忽略 PHPDoc 注解,与
\PHPStan\dumpType()形成互补; - 修复方式:删除调试调用,不要忽略该错误;
- 应用场景:排查 PHPDoc 与真实代码类型不一致、验证类型窄化结果、快速了解 PHPStan 的推断逻辑。
参考文档:phpstan.dumpNativeType.md、phpstan.dumpType.md。
【免费下载链接】phpstanPHP Static Analysis Tool - discover bugs in your code without running it!项目地址: https://gitcode.com/gh_mirrors/ph/phpstan
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考