composer-unused是唯一能落地的冗余依赖扫描方案,它通过扫描PHP源码识别真实使用情况,而composer install和composer show仅管理安装与列表,不分析代码调用,无法识别未使用包。

只能用 composer-unused,其他命令(比如 composer show --unused)根本不存在。
为什么 composer install 和 composer show 都不能检测未使用包
Composer 本身不读你的 PHP 文件。它只按 composer.json 安装、按 autoload 规则注册类,但完全不管代码里有没有 use、new、class_exists() 这些实际调用痕迹。运行 composer show 只是列出 vendor/ 里有什么,和“有没有被用”毫无关系。
常见错误现象:
-
composer outdated只比对版本,不涉及是否被引用 -
composer why some/package返回空,不代表没被用——可能只是被另一个 require 包间接拉进来的“幽灵依赖” - 手动
grep -r类名容易漏:别名导入(use Foo\Bar as B)、动态类名(new $className)、配置文件字符串("monolog/handler/stream")全都不识别
composer-unused 默认只扫 src/ 和 tests/,你得告诉它去哪找
它默认跳过 bin/、app/、config/、database/ 等目录,哪怕你的入口文件 bin/console 或服务提供者在 app/Providers/ 里用了某个包,也会被漏掉。
实操建议:
- 先确认业务代码路径:Laravel 通常在
app/,Symfony 在src/,自定义框架可能在lib/或core/;用--scan-dir app显式指定 - 加
--include-tests才会扫描tests/下的调用,否则测试里用的guzzlehttp/guzzle会被标为 “unused” - 加
--autoload强制加载composer.json中的 autoload 规则,避免因 PSR-4 映射不全导致类找不到 - 排除干扰路径:
--exclude vendor --exclude tests --exclude var --exclude storage
典型命令示例:composer-unused --no-progress --scan-dir app --include-tests --autoload --exclude vendor --exclude var
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
哪些标为 “unused” 的包其实删不得
composer-unused 是静态分析工具,对运行时行为完全无感。以下三类情况必然误报,但删了就炸:
-
doctrine/annotations、phpstan/phpstan:没use,靠反射解析注解或扩展机制加载 -
symfony/dotenv、laravel/tinker、spatie/laravel-permission:逻辑藏在配置、migration 或 artisan 命令里,源码层无直接引用 -
symfony/polyfill-*、monolog/monolog:副作用型包,加载即注册函数或 handler,连class_exists()都不会触发
处理方式不是硬删,而是建白名单:composer-unused.php 配置中加 $configuration->whitelist(['doctrine/annotations', 'symfony/dotenv']);,或运行时用 --exclude "doctrine/annotations,symfony/dotenv"。
CI 中跑 composer-unused 容易失败的几个坑
CI 环境下内存小、autoload 不全、路径缺失,是假阴性高发区。
必须做的几件事:
- 先执行
composer install --no-dev(或保留--dev,看你检测范围),再composer dump-autoload --classmap-authoritative,确保 autoload 信息完整 - 设环境变量
COMPOSER_MEMORY_LIMIT=-1,防止 OOM 中断 - 不要在
composer.lock变更后立刻扫描——新包可能还没写调用,建议等至少一个 commit 周期后再检查 - 若用 GitHub Actions,记得把
~/.composer/vendor/bin/加进$PATH,否则报command not found
最易被忽略的一点:composer-unused 不理解 DI 容器的 bind()、resolve() 或 Laravel 的 App::make(),这类注入型依赖永远需要人工交叉验证——工具能告诉你“没看到调用”,但不能替你判断“该不该留”。

















