PHPStan必须本地安装,全局安装会导致配置不加载、类找不到、扫描静默失效;正确做法是项目根目录执行composer require --dev phpstan/phpstan并配置phpstan.neon于根目录。

PHPStan 必须本地安装,全局安装等于没装——配置不加载、类找不到、扫描静默失效。这不是 bug,是设计使然。
composer require --dev phpstan/phpstan 为什么总失败?
失败通常不是网络或权限问题,而是环境或版本链路断了。
- 在子目录(如
src/或tests/)里执行命令:必须回到项目根目录(含composer.json)再运行 -
composer.json里已有旧版锁定(比如"phpstan/phpstan": "^0.12"):手动改成"^1.10"或"^2.0",再执行composer update phpstan/phpstan - 误用过
composer global require phpstan/phpstan:先运行composer global remove phpstan/phpstan,再重装本地版 - 装了
nunomaduro/larastan却没装phpstan/phpstan:Larastan 是扩展包,不是可执行主体,缺核心就报Command not defined
phpstan.neon 配置不生效的典型表现
运行 vendor/bin/phpstan analyse 显示 [OK] No errors,但代码里明显有类型错误或未定义方法调用——说明配置根本没被读到。
- 文件名必须是
phpstan.neon(不能是phpstan.yaml、.neon、phpstan.neon.dist)且放在项目根目录 - 必须包含
parameters:块,level和paths要在其下缩进(YAML 对空格敏感,推荐用 2 空格) -
paths默认只扫src/;Laravel 项目要加- app/、- database/、- routes/,否则直接跳过 - 纯函数文件(如
src/helpers.php)无命名空间:必须显式写autoload_files: ["src/helpers.php"],否则函数调用全标为 undefined
vendor/bin/phpstan analyse 什么都没扫到?用 --debug 验证
PHPStan 不会主动提示“配置没读到”,它只会安静 fallback 到 level 0 + 只扫 src/ + 跳过所有 autoload 映射。最快速验证方式:
立即学习“PHP免费学习笔记(深入)”;
- 运行
vendor/bin/phpstan analyse --debug,看输出里Loaded configuration是否指向你写的phpstan.neon - 检查
Scanning files in后列出的路径是否包含你预期的目录(如app/Models/User.php) - 若看到
Using bootstrap file: vendor/autoload.php,说明自动加载链路通;若没这行,autoload_files或composer dump-autoload -o没到位 - CI 环境中常见陷阱:
phpstan.neon被.gitignore忽略、composer install --no-dev跳过了 dev 依赖、工作目录不是项目根目录
Laravel 项目报一堆 Call to undefined method 怎么办?
这不是 PHPStan 的问题,是它默认不认识 Laravel 的运行时特性(Facade、模型属性、容器绑定)。必须补两层:
- 装三个包:
composer require --dev phpstan/phpstan phpstan/phpstan-laravel phpstan/extension-installer——漏掉phpstan/extension-installer,扩展规则不会自动加载 - 在
phpstan.neon中显式引入扩展:includes: - vendor/phpstan/phpstan-laravel/extension.neon - 启用模型扫描(可选但推荐):
parameters: { scanModels: true },否则User::$name这类属性始终报错 - 别把
tests/加进paths却不配autoload-dev:否则测试里用的TestCase类会报Class not found
真正难的不是装上 PHPStan,而是让它的符号解析和你的项目结构对齐——特别是当项目混用 PSR-4、files autoload、Laravel Facade 或自定义引导逻辑时,少一个配置点,就会满屏 “undefined”。



















