Composer不支持按操作系统条件安装包,唯一可控方式是通过config.platform模拟目标环境扩展能力,并配合上游包声明的ext-xxx依赖实现伪条件安装。

怎么用 config.platform 声明扩展并触发校验
Composer 不会自动检查你本地有没有启用某个扩展,除非你在 require 里明确写上 "ext-curl": "*",并且配合 config.platform 做“环境模拟”。否则 composer install 可能成功,但上线后直接报 Call to undefined function curl_init()。
关键点是:只有 require 中声明了 ext-*,且 config.platform 里也写了对应扩展(哪怕值为 "0"),Composer 才会在安装时比对本地是否真有该扩展。
-
ext-redis必须和php -m输出的模块名完全一致(小写、带下划线,不能写成ext-redis-php或redis) - 扩展版本号基本无意义,写
"*"或留空即可;"^5.3"这类写法无效 - 如果生产环境没有
ext-igbinary,但你本地装了,又没在require里声明它,Composer 就不会报错——必须靠config.platform显式“降级”可用扩展集来暴露问题
--platform=ext-xxx 命令行参数为什么比 composer.json 更可靠
config.platform 在 composer.json 里只影响 update 阶段的依赖解析,对 install 阶段的 lock 文件校验几乎无效。比如你用 PHP 8.3 生成了 composer.lock,再拿到 PHP 8.1 环境执行 composer install,即使 composer.json 里写了 "php": "8.1.28",它也不会重新检查扩展是否存在。
真正起效的是命令行参数:--platform 在 install 和 update 两个阶段都强制覆盖平台信息,且优先级最高。
立即学习“PHP免费学习笔记(深入)”;
- 临时测试 PHP 8.1 + 无
ext-gd环境:composer install --platform=php:8.1.28 --platform=ext-gd:0 - 想跳过某个扩展的检查(如 CI 中临时禁用
ext-opcache):--platform=ext-opcache:0 - 多个
--platform可叠加,顺序无关,例如:--platform=php:7.4.33 --platform=ext-mbstring:* --platform=ext-xml:0
常见错误现象:为什么加了 platform 还是报语法错误
加了 "php": "8.1.28" 后 composer install 成功,但运行时报 ParseError: syntax error, unexpected token "readonly" —— 这说明 config.platform.php 只管依赖选择,不管代码本身是否兼容。
- 它不会阻止你 require 一个内部用了
readonly类属性的包(该特性 PHP 8.2+ 才支持) - 它也不屏蔽你本地 PHP 8.2 的语法特性,所以你写的代码可能无意中用了高版本语法
- 真正要提前发现问题,得配合多 PHP 版本环境:用
phpbrew或Docker切到目标 PHP 版本,再跑composer install+php -l+ 单元测试
CI/CD 中怎么稳定复现目标扩展环境
GitHub Actions、GitLab CI 这类环境默认只有一个 PHP CLI,但往往缺少某些扩展(比如 Alpine 镜像默认没 ext-pdo_mysql)。光靠 config.platform 无法让 Composer 自动装扩展,它只是个校验开关。
- 先确保基础镜像已启用所需扩展,例如 GitHub Actions 中用
shivammathur/setup-php@v2时显式传参:extensions: mbstring, pdo, pdo_mysql, curl - 再用
--platform参数强制校验,避免因 CI 配置遗漏导致漏检 - 部署脚本中禁用
--ignore-platform-reqs—— 这个参数会绕过所有 platform 检查,只应在调试锁文件时临时使用
最易被忽略的一点:platform 配置不解决扩展编译兼容性问题。比如 ext-redis 在 PHP 8.1 下编译的 so 文件,在 PHP 8.2 运行时可能因 ABI 不兼容直接 segfault,这已经超出 Composer 的管控范围。



















