composer 的 platform 配置必须写在 composer.json 顶层、与 require 同级,格式为 "platform": {"php": "8.1.25"};写在 config.platform 或其他路径均无效,且需删除 composer.lock 和 vendor/ 才能生效。

Composer 没有“给某个包添加安装条件”的语法,所谓“条件安装”本质是靠 platform 模拟环境 + require 版本约束共同作用的结果;单独写个 if-else 或 environment 字段会直接被忽略。
为什么 config.platform.php 写了却没用?
因为 config.platform 根本不存在——Composer 官方不识别这个路径。你写的配置会被完全跳过,composer install 依然按你本地真实 PHP 版本选包。
- 正确位置是 composer.json 的**顶层字段**,和
require同级,写成:"platform": { "php": "8.1.25" } - 写成
"config": { "platform": { ... } }❌,写成"platform.php": "8.1.25"❌,写成"php-platform": { ... }❌ - 改完必须删掉
composer.lock和vendor/,否则旧锁文件缓存了之前解析结果,新platform形同虚设
如何让某个包只在有 ext-gd 时才装?
你不能控制“是否安装”,但可以让 Composer 在缺失 ext-gd 时,自动避开那些声明了 "ext-gd": "*" 的包版本——前提是目标包自己在 composer.json 中正确声明了扩展依赖。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 在你自己项目的
composer.json中加:"platform": { "ext-gd": "*" } - 这会让 Composer “假装”当前环境已启用 gd 扩展,从而允许安装依赖
ext-gd的包(如intervention/imagev3) - 但如果线上真没装
ext-gd,运行时仍会报Call to undefined function gd_info()——platform不校验真实环境 - 想跳过运行时检测?CI 中可临时加:
COMPOSER_PLATFORM_CHECK=0 composer install --no-dev
require.php 和 platform.php 冲突了怎么办?
它们不是同一类东西,不会“冲突”,但容易误用:一个管硬性约束,一个管模拟选择。
-
"require": { "php": "^8.1" }是硬门槛:本地 PHP 是 8.0,composer install直接报错退出 -
"platform": { "php": "8.0.30" }是软欺骗:本地是 8.2,它会让 Composer 假装自己在 8.0 下跑,从而避开 require 了php: ^8.1的包 - 两者同时存在时,
require.php优先级更高;若你设platform.php为 8.0,但require.php是^8.1,composer update会因约束矛盾失败 - 常见翻车点:把
php错写进require-dev—— 它只约束 dev 包,不影响主项目 PHP 校验
CI/CD 中怎么临时指定平台而不污染 git?
别改 composer.json,用命令行动态写入当前目录的 config,且只影响本次执行。
- CI 脚本中执行:
composer config platform.php 8.0.30 - 这条命令会把
"platform": { "php": "8.0.30" }写入当前 composer.json 的config字段?不,它实际写的是顶层platform字段(Composer 内部做了映射) - 更稳妥的做法是加
--no-plugins防插件干扰:composer config platform.php 8.0.30 --no-plugins - 执行完立刻
composer install --no-dev,避免 dev 依赖拉取高版本包
最易被忽略的一点:platform 只影响依赖解析那一刻的选择,它不阻止你用 PHP 7.4 去跑一个 require 了 php: ^8.2 的项目——直到代码里出现 match 表达式或只读属性,才会在运行时报错,而不是安装时报错。










