phpstan 的 ignoreerrors 不能排除 vendor/ 目录,因为它只匹配已触发的错误,而 vendor/ 默认不被扫描;正确做法是通过 scandirectories 或 autoload_paths 限定分析范围,避免 vendor/ 进入扫描链。

PHPStan 的 ignoreErrors 为什么不能直接排除 vendor/ 目录?
因为 ignoreErrors 是错误匹配规则,不是路径过滤器——它只对已触发的报错生效,而 PHPStan 默认根本不会分析 vendor/ 下的代码。所以你加了 ignoreErrors 去“忽略 vendor 报错”,大概率什么都不会发生,因为那些文件压根没被扫描。
真正要做的,是让 PHPStan 别去读 vendor/,而不是事后“忽略”它的错误。
正确做法:用 scanDirectories 或 autoload_paths 显式限定分析范围
PHPStan 默认会从 autoload 配置(如 composer.json 中的 autoload 和 autoload-dev)推导要分析的目录。如果你的 composer.json 里写了 "autoload": {"psr-4": {"App": "src/"}},那它默认就只扫 src/;但一旦你用了 "autoload": {"psr-4": {"": "src/", "": "tests/"}} 这类宽松配置,或启用了 scanFiles,就可能意外带入 vendor/ 中的文件。
- 检查
phpstan.neon是否误配了scanDirectories: [vendor/]或scanFiles列表里包含vendor/下的文件 - 确保
autoload段只声明你自己的命名空间,不要写"": "vendor/some-lib/src"这种反模式 - 如果必须手动指定路径,用
scanDirectories: [src/, tests/],**别写vendor/,也别留空数组
ignoreErrors 真正该用在哪?
它适合处理「已知的、无法修改的第三方代码调用引发的误报」,比如你在自己的代码里用了某个库的函数,PHPStan 因类型不完整报错,但你确认没问题——这时才轮到 ignoreErrors 出场。
立即学习“PHP免费学习笔记(深入)”;
示例场景:你调用了 monolog/monolog 的 Logger::info(),但 PHPStan 提示参数类型不匹配(因 PHPDoc 不全),而你又不想改库代码:
parameters: ignoreErrors: - '#Call to an undefined method MonologLogger::info()#'
注意:ignoreErrors 的正则必须转义反斜杠,且匹配的是完整错误消息文本,不是文件路径。
一个容易被忽略的兼容性坑:vendor/ 被扫描的隐性原因
某些 ide 插件或 CI 脚本会把 phpstan analyse vendor/ 当成“深度检查”,这是错的。更隐蔽的是:如果你项目用了 nikic/php-parser 或其他依赖源码分析的工具,并在 phpstan.neon 里通过 includes: 引入了它们的配置,而那些配置本身打开了 vendor/ 扫描,就会穿透进来。
排查方法很简单:
- 运行
phpstan analyse --debug src/YourClass.php,看输出里有没有vendor/下的文件路径 - 临时注释掉
phpstan.neon中所有includes:,再试一次 - 检查是否在
composer.json的scripts里拼错了命令,比如写成"phpstan analyse ."
vendor 目录不该出现在 PHPStan 的分析视野里,不是靠忽略错误来解决的,而是从入口路径上掐断。一旦发现它进了扫描链,说明配置或调用方式有偏差,得顺藤摸瓜找源头。