Composer 不支持按环境切换依赖,其 composer.json 是静态声明式配置;需通过 require-dev 隔离开发依赖、config.platform 模拟生产环境、或运行时判断等方式间接实现。

Composer 本身不支持按环境切换依赖
直接说结论:Composer 的 composer.json 是静态声明式配置,没有 if environment === "prod" 这种逻辑。所谓“不同环境加载不同依赖”,本质是人为拆分依赖用途,并通过约束条件或工作流控制安装行为。
用 require-dev 隔离开发专用依赖
这是最常用、最安全的做法。把仅在本地开发或 CI 中需要的包(如 phpunit/phpunit、laravel/pint、symfony/var-dumper)全部放进 require-dev,生产部署时加 --no-dev 参数跳过它们:
composer install --no-dev
注意:--no-dev 不仅跳过安装,还会从自动加载中排除这些包——这点常被忽略,导致误用 class_exists('PHPUnit\Framework\TestCase') 在生产报错。
-
require-dev中的包在autoload-dev下定义的类,不会出现在生产环境的vendor/autoload.php中 - 若某包既用于开发又需在生产运行(比如调试用的
barryvdh/laravel-debugbar),不能放require-dev,得另寻方案 - CI 环境应始终运行
composer install(不带--no-dev),确保测试工具可用
用平台配置和 config.platform 模拟目标环境
当你的生产环境 PHP 版本或扩展与本地不一致(例如本地是 PHP 8.3,生产是 PHP 8.1),Composer 可能因依赖版本冲突无法安装。这时用 config.platform 强制 Composer 按生产环境解析依赖:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
"config": {
"platform": {
"php": "8.1.28",
"ext-mbstring": "8.1.28",
"ext-redis": "5.3.7"
}
}
它不会改变你本地 PHP 实际版本,但会让 composer update 选出兼容生产环境的包版本。常见坑:
- 漏写关键扩展(如
ext-pdo_mysql),导致线上报Class 'PDO' not found - 设了
platform.php却没同步到 CI,造成 CI 和生产依赖不一致 -
platform对require-dev同样生效——如果你在本地开发用高版本 PHP 特性,而platform锁太死,phpunit可能降级到不兼容的旧版
用脚本钩子 + 环境变量做轻量级条件加载(不推荐但可行)
极少数场景下,你确实需要某个包只在 APP_ENV=local 时存在(比如一个仅供本地调试的 mock 服务 SDK)。Composer 不支持条件 require,但可以绕过:
- 把该包放在
require-dev,再在代码里用class_exists()或extension_loaded()做运行时判断 - 写自定义 Composer 脚本(如
post-install-cmd),根据$_SERVER['APP_ENV']或文件是否存在,执行composer require xxx --dev——但会破坏依赖声明的可追溯性,CI 和团队协作时容易出问题 - 更稳妥的方式:把这个“条件依赖”打包成一个独立的私有包,内部用
autoload-files加载环境判断逻辑,主项目无条件 require 它,由它自己决定是否激活功能
真正难处理的不是“怎么装”,而是“装完后如何让代码不炸”。环境差异最终都会落到运行时行为上,Composer 只管依赖树,不保 runtime 兼容性。

















