composer-unused是目前唯一通过扫描php代码中use、new等实际引用反向检测冗余依赖的工具,它不依赖autoload或require声明推测,但无法识别反射、动态类名、配置绑定等间接使用,误报率高,需人工验证并配合白名单过滤。

没有内置命令能可靠检测未使用依赖,必须用 composer-unused —— 它是目前唯一通过实际代码引用(use、new、static:: 等)反向扫描的工具,不是靠 autoload 或 require 声明猜的。
为什么 composer why 和 composer show --tree 不能替代检测
composer why vendor/package-name 只回答“谁声明了它”,不回答“你代码里有没有真用”。比如 phpunit/phpunit 被 require-dev 声明,composer why 会显示“根项目”,但它可能一行 use 都没写;composer show --tree 展示的是依赖图谱,不是调用图谱——一个包被拉进来,不代表你的 PHP 文件里调用了它的任何类或函数。
常见误判场景:
-
symfony/flex在composer.json的bin字段里被调用,但源码无use,composer-unused会报它“未使用”,这是对的,因为确实没被 PHP 代码引用 -
doctrine/annotations全程靠反射解析注解,代码里没有use DoctrineCommonAnnotationsAnnotation,composer-unused必然标为冗余,但删不得 - CI 脚本里写了
vendor/bin/php-cs-fixer,但项目 PHP 文件里没出现该包任何符号,composer-unused不会把它当“已使用”
怎么正确运行 composer-unused 避免大面积误报
默认行为会扫描 tests/、vendor/、var/ 等目录,导致结果污染。必须显式排除无关路径,并控制扫描范围:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 全局安装后,先确认 PHP 版本兼容:
composer-unusedv0.12.x 要求 PHP ≥ 8.1;若项目还在 PHP 7.4,得降级到 v0.9.11,否则直接报ParseError: unexpected token "readonly" - 生产环境视角扫描(跳过所有 dev 相关):
composer-unused --no-progress --exclude tests --exclude vendor --exclude var --no-dev - 想包含测试中的使用?加
--include-tests,但别忘了同时加--exclude vendor,否则 vendor 内部的use会被误认为“项目在用” - 首次运行建议加
--no-progress,避免 CI 日志刷屏;输出中每行末尾的 confidence 级别(low/high)可辅助判断是否值得人工复查
哪些“未使用”其实不能删,怎么白名单过滤
composer-unused 不分析运行时行为,所以以下三类必然误报,需人工核对并加白名单:
- 注解驱动:如
doctrine/annotations、phpstan/phpstan扩展,它们靠字符串反射加载类,代码里不会use - 配置驱动:如 Symfony 的
config/packages/cache.yaml里写了framework.cache.type: pool,背后依赖symfony/cache,但 PHP 文件里无调用痕迹 - CLI 工具型包:如
laravel/pint、spatie/phpunit-snapshot-assertions,只在composer.json的bin或脚本中出现
在项目根目录建 composer-unused.php:
<?php return [
'whitelist' => [
'doctrine/annotations',
'phpunit/phpunit',
'laravel/pint',
],
];
注意:whitelist 里的包名必须和 Packagist 上注册的全名一致,大小写、斜杠都不能错。
最麻烦的永远不是工具跑不跑得通,而是看到一行“monolog/monolog not used”时,得立刻 grep -r "Monolog\" src/ config/ --include="*.php" 确认——有些调用藏在 migration、Console 命令或服务提供者里,composer-unused 扫不到,但删了就炸。










