composer remove 是最安全标准的卸载方式,它删除声明并同步清理:从 composer.json 移除条目、删 vendor 目录、更新 lock 文件和 autoload;若包被其他依赖硬需则报错保护;开发依赖自动识别,--with-dependencies 可连带删手动添加的依赖;删后须检查 JSON/lock 差异、重生成 autoload、确认 vendor 清空,并人工审查代码中残留引用。

composer remove 是当前最安全、最标准的卸载方式,它不是“删文件”而是“删声明+同步清理”,只要包没被其他已安装依赖硬性需要,就能干净移除。
直接卸载一个包:用 composer remove vendor/package-name
这是日常最常用场景,比如你想去掉日志库:
composer remove monolog/monolog命令会自动完成三件事:
- 从
composer.json的require或require-dev中删掉对应行 - 删除
vendor/monolog/monolog/目录 - 更新
composer.lock并重生成 autoload 映射
symfony/console)依赖,Composer 会立刻报错并中止,这不是失败,是保护机制——说明你不能直接删它,得先查清依赖链。
开发依赖要加 --dev,但不加也不一定错
像 phpunit/phpunit 这类只在测试时用的包,通常装在 require-dev 里。你可以显式写:
composer remove --dev phpunit/phpunit但其实不加
--dev 也行:composer remove phpunit/phpunit 会自动识别它在 require-dev 区域并正确处理。只有当你同时在 require 和 require-dev 里都写了同一个包(极少见),才需要指定参数避免误删。
想一并清理它的子依赖?别信“自动全清”,要分情况看
Composer 默认不删间接依赖,比如你删了 guzzlehttp/guzzle,它依赖的 psr/http-message 可能还留着——因为 symfony/http-client 也在用它。
- 若某个子依赖(如
guzzlehttp/promises)只被刚删的包引用,且没出现在其他包的require列表里,Composer 会在update阶段顺手清掉 - 若你想强制连带删掉你在
composer.json里手动加过的直接依赖(比如你曾单独require过psr/http-message),可用--with-dependencies:composer remove --with-dependencies guzzlehttp/guzzle
但注意:这个选项只删你composer.json里写的依赖项,不管别人是否共用;误用可能导致其他功能报Class not found - 真正确认“孤儿依赖”,得靠
composer why psr/http-message:如果输出为空,才是真没人要
删完必须检查的三个地方
别急着提交或部署,立刻验证:
-
git diff composer.json composer.lock:确保只有目标包被删,没意外动到其他require条目 - 运行
composer dump-autoload:防止旧 autoload 缓存导致类还能加载(看似删了实则还在) - 执行
composer show | grep package-name或ls vendor/ | grep package-name:确认vendor/和 Composer 内部索引都清空了
nesbot/carbon 的辅助函数),删后可能报 Call to undefined function,这种得配合代码搜索一起处理。
真正容易被忽略的是:删包只是起点,不是终点。依赖图是活的,composer remove 解决的是“声明层”的移除,而项目里是否还有 use、new、function_exists 等硬引用,它管不了——那得靠你自己的代码审查和测试兜底。










