depcheck不可用因其基于停滞的AST分析,不支持PHP 8+类型语法,误将所有require-dev标为冗余,且无法识别框架动态加载(如Laravel命令注册),还存在Composer插件API兼容问题。

composer-unused 是目前唯一能稳定落地的未使用依赖检测工具,其他方案要么已停更、要么误报率高到无法信任。
为什么 depcheck 不能用
depcheck 基于老旧 AST 分析,对 PHP 8+ 类型语法(如 mixed、never、联合类型)解析失败,运行时直接报错或跳过文件。它默认把所有 require-dev 标为冗余,哪怕你项目里有 phpunit 和完整的测试套件,也会被标红。更关键的是它不识别框架约定式加载——比如 Laravel 的 bin/console 里通过 $application->add() 注册命令,depcheck 完全看不到调用链,直接误判 symfony/console 为“未使用”。安装后还可能触发 Plugin Manager is not available 错误,因为它的 Composer 插件 API 已不兼容 2.5+ 版本。
composer-unused 的真实能力边界
它靠扫描 vendor/ 下所有 PHP 文件,再反向查找项目代码中 use、new、class_exists、interface_exists 等硬引用痕迹,比只看 autoload 配置靠谱得多。但它不是万能的:
- 动态类名(如
new $className、class_alias、配置文件里的字符串类名)完全无法覆盖 - 不解析 Twig/Blade 模板、YAML/JSON 配置中的类引用
- 默认跳过
tests/目录,得加--scan-tests才能识别测试专用依赖 - 默认只扫
src/,如果你的业务逻辑在app/或lib/,必须用--scan-dir=app显式指定 - DI 容器注入的实现类(如接口 + 实现类 +
bind())不会被标记为“已使用”,需配合 PHPStan 先做类型检查
运行前必须确认的三件事
结果准不准,不取决于工具本身,而取决于环境是否就绪:
-
composer install必须已执行完毕,否则vendor/缺文件,扫描结果漏报严重 - 项目里不能有未提交的临时调试代码(比如手写的
var_dump引用了某个包但还没删),否则会干扰判断 - 如果用了 Psalm 或 PHPStan,建议先跑一遍
vendor/bin/phpstan analyse,避免因类型错误导致composer-unused误判“某类没被引用”
真正难的从来不是装一个命令,而是搞清哪些“未使用”是安全可删的,哪些是框架强依赖但代码里没显式调用的——后者删了不会立刻报错,但下次运行 php artisan tinker 或 bin/console 就会崩。











