composer require 必然触发更新行为,因其本质是修改 composer.json 后自动执行受限范围的 update、更新 composer.lock、下载并安装包到 vendor/,不存在仅声明不安装的内置模式。

Composer 无法在不运行 composer update 或 composer install 的前提下真正“安装”新包——require 命令本质就是触发依赖解析与安装,它内部会自动执行类似 update 的流程。
为什么 composer require 必然触发更新行为
composer require 不是单纯写入 composer.json,它默认会立即下载、安装并写入锁文件。其底层逻辑等价于:
- 修改
composer.json的require字段 - 运行
composer update vendor/package-name --with-dependencies(受限范围的 update) - 生成 / 更新
composer.lock - 下载并 解压 包到
vendor/
所以不存在“只加声明、不装代码”的内置模式。强行跳过安装步骤会导致 vendor/ 缺失文件、自动加载失效、CI 失败。
想跳过安装?只能手动编辑 + 后续补救
若因网络 / 权限 / 环境限制暂时不能下载,可绕过 require 命令,纯手工操作,但必须清楚后果:
- 直接用文本编辑器向
composer.json的require中添加条目,例如:"monolog/monolog": "^3.0" - 删掉现有
composer.lock(否则install时会按旧锁文件还原) - 后续必须运行
composer install或composer update monolog/monolog才能真正生效 - 此时
autoload不会包含该包,class_exists()或use语句会报错
require --no-update 是什么?它并不省事
这个选项仅跳过“安装”动作,但仍会修改 composer.json 并尝试更新 composer.lock 的哈希与元数据——但它不会下载任何文件,也不会写入 vendor/。实际效果非常有限:
- 执行后
vendor/里没有新包,composer dump-autoload也无法识别新命名空间 -
composer.lock可能处于不一致状态:记录了未安装的包版本,但无对应 dist/source 信息 - 下次运行
composer install会失败,提示Package monolog/monolog not found
它只适合极少数场景:比如你正在写 CI 脚本,需预写依赖再统一 install;或你明确计划立刻跟一个 composer install --no-interaction。
真正可控的“延迟安装”方案:用 platform 或 repositories 配合 require
如果你的目标是“先确认兼容性、再决定是否装”,推荐组合使用配置项降低风险:
- 加
--dry-run预览变更:composer require monolog/monolog --dry-run,看会升级哪些依赖、有无冲突 - 锁定 PHP 版本避免误升:
"config": {"platform": { "php": "8.1.22"} },防止require因本地 PHP 版本高而选不兼容的包版本 - 指定私有源减少不确定性:
"repositories": [{"type": "composer", "url": "https://packages.example.com"}]
这些不是跳过安装,而是让 require 这次安装更确定、更安全。
{"require": { "php": "^8.1", "monolog/monolog": "^3.0"}, "config": {"platform": { "php": "8.1.22"} }, "repositories": [{ "type": "composer", "url": "https://packages.example.com"} ] }
最常被忽略的一点:很多人以为 --no-update 能“先记下来”,结果忘了后续补 install,导致本地开发和线上行为不一致——锁文件没更新、vendor 缺文件、错误直到部署才暴露。