composer-unused 能发现声明但未被 php 代码直接引用的依赖,但无法识别反射、动态类名、配置绑定等间接使用,误报率高,需人工验证。

直接说结论:composer-unused 能发现项目中「声明了但完全没被 PHP 代码引用」的依赖,但它无法识别运行时加载、反射调用、配置驱动或字符串拼接类名等间接使用方式——误报率不低,需人工验证。
为什么 composer-unused 会把真实依赖标成“未使用”
它只扫描 .php 文件里的 use 语句、new、static::、self::、parent:: 和函数调用(含命名空间前缀),不解析:
-
class_exists('Vendor\Package\SomeClass')—— 反射判断,跳过 -
$class = 'App\Service\Mailer'; new $class()—— 字符串动态实例化,跳过 -
config/services.php中通过字符串注册的容器绑定 - PHP 扩展(如
ext-redis)或命令行工具(如phpunit)的 dev-only 依赖
典型误报:Laravel 项目里用了 spatie/laravel-permission,但所有权限逻辑都在 migration 和 artisan 命令中 —— composer-unused 扫不到,直接标为冗余。
如何让 composer-unused 结果更可信
别直接删,先做三件事:
- 加
--no-dev参数只检查生产依赖,避免把phpunit、larastan这类纯开发工具误伤 - 用
--whitelist显式保留已知间接使用的包,例如:composer-unused --whitelist="spatie/laravel-permission,doctrine/inflector" - 配合
grep -r快速验证:如果它说monolog/monolog没被用,立刻执行grep -r "Monolog\" app/ config/ --include="*.php"看是否真没出现
注意:composer-unused 默认不扫描 tests/ 目录,如果你的集成测试里用了某包,而主代码没用,它也会报“未使用”——这时加 --scan-tests 更准。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
composer-unused 的安装和最小可行检查流程
推荐全局安装(避免污染项目):
composer global require composer-unused/composer-unused
然后在项目根目录运行:
composer-unused --no-progress --no-dev
关键参数含义:
-
--no-progress:关掉进度条,输出更干净,方便 grep 或重定向 -
--no-dev:只检查require,忽略require-dev -
--json:输出 JSON,适合 CI 中解析(但人眼不友好) -
--min-confidence=high:只报告高置信度结果(默认是medium,会多报)
CI 中建议加 --fail-on-unused 配合 --min-confidence=high,避免误触发失败。
最麻烦的地方不是工具不会用,而是得花时间区分:到底是真冗余,还是你没写全调用路径。尤其在 Laravel、Symfony 这类靠容器和配置驱动的框架里,composer-unused 的“未使用”警告,八成需要打开 config/ 和 routes/ 手动翻一遍。










