Composer install 在 CI 上报“required PHP extension xyz missing”错,因它默认按本地环境解析依赖而非目标环境;platform 配置须写在 composer.json 的 config 段中,显式声明目标 PHP 版本与扩展,仅影响依赖解析。
为什么
在 CI 上报错 “required PHP extension xyz missing”?
因为 Composer 默认按当前运行环境(比如你本地 PHP 8.2 + ext-redis)解析依赖,但 CI 或生产环境可能是 PHP 7.4 且没装
。它不是“检测目标环境”,而是“信任当前环境”。
就是用来显式声明“我最终要跑在什么 PHP 版本和扩展上”的机制。
配置写在哪?怎么写才生效?
必须写在
的
段里,不是
或
。它只影响依赖解析阶段,不安装任何东西。
常见写法:
注意:
的版本号可以写
(表示“只要存在就行”),但部分包(如
)会检查扩展版本是否 ≥ 某值,这时写死更稳妥。
PHP 版本必须严格匹配目标环境的
输出主版本+次版本(如
),否则可能选错包分支
扩展名大小写敏感:
✅,
❌
如果只配
不带小版本,Composer 会按语义化版本规则解释为
,可能意外允许
解析结果
配置了
还是装不上包?检查这三点
最常见原因不是配置错,而是没触发平台约束逻辑:
Composer 2.9.6
Composer 2.9.6 是 PHP 生态中高效、稳定的依赖管理工具。此版本在性能与兼容性上进一步优化,改进了依赖解析算法,提升大型项目中的安装与更新速度。它支持并行下载任务,显著减少等待时间,并增强了与私有仓库及镜像源的交互稳定性。同时修复了多项命令行交互与内存使用相关的缺陷,确保在复杂依赖关系下依然可靠运行。无论是新项目初始化还是现有系统维护,Composer 2.9.6 都能为开发者提供流畅、精准的依赖管理体验。
下载
时,
仅影响新解析的依赖树;已有
会优先沿用其中记录的版本 —— 必须加
或删 lock 文件重装
用了
(CI 脚本里常有),这个 flag 会直接无视
配置
某些包通过
声明虚拟扩展(如
提供
),此时
中的
可能被绕过 —— 真实环境没扩展时,polyfill 不一定能完全替代
PHP 版本和扩展不一致时,
怎么取舍?
没有取舍 —— 它必须反映真实部署环境的最小交集。例如:
你的应用要同时跑在阿里云函数(PHP 8.0 + ext-redis)和某老 CentOS(PHP 7.4 + 无 ext-redis),就不能在
里写
,否则
在 7.4 环境会失败。正确做法是:要么放弃 redis 功能、改用文件缓存;要么把 redis 相关代码隔离进可选的
或插件机制。
真正容易被忽略的是:扩展的 ABI 兼容性。比如
在 PHP 8.0 和 8.1 下二进制不兼容,即使
写了
,也得确保扩展版本与 PHP 版本实际匹配 ——
不校验这个,只管 Composer 解析逻辑。
composer installext-redisplatformplatformcomposer.jsonconfigrequirerequire-dev
{
"config": {
"platform": {
"php": "7.4.33",
"ext-gd": "8.1.0",
"ext-mbstring": "8.1.0",
"ext-redis": "5.3.7"
}
}
}
ext-xxx*symfony/cachephp -v8.1.27ext-curlext-CURL"php": "8.1"^8.18.2platformcomposer updateplatformcomposer.lock--with-all-dependenciescomposer install --ignore-platform-reqsplatformprovidesymfony/polyfill-mbstringext-mbstringplatformext-mbstringplatformplatform"ext-redis": "*"composer installrequire-devext-redis 5.3.7platform"php": "8.0"platform