Composer 的 platform 配置是在 composer.json 中通过 "platform" 字段手动声明项目“假装运行的 PHP 环境”,优先于真实环境决定依赖解析,确保本地安装与生产环境一致。

Composer 的 platform 配置是啥?
它是在 composer.json 里用 "platform" 字段手动声明当前项目“假装运行在什么 PHP 环境下”的机制。Composer 本身不读取你本地 php -v 的结果来决定装哪些包——它优先看 platform,再 fallback 到真实环境。这直接决定了 require 里带 PHP 版本约束的包(比如 "php": "^8.1")能不能被安装、以及是否拉取兼容版本。
为什么需要模拟生产 PHP 版本?
常见于本地开发机是 PHP 8.3,但线上是 PHP 8.1。若不干预,Composer 可能装入仅兼容 8.3 的扩展或依赖(比如用了 #[\Override] 的库),部署后直接报 ParseError 或 Class not found。用 platform 就能让 composer install 在本地也严格按生产环境选包。
- 它只影响依赖解析阶段,不影响实际代码运行(你的 PHP 8.3 还是跑得动 8.1 的代码)
- 不会改写
vendor/里的源码,只是让 Composer 拒绝下载不兼容的版本 - CI/CD 中也建议显式配置,避免因 runner 环境变动导致构建结果不一致
怎么配置 platform 模拟生产 PHP 版本?
在 composer.json 的根对象里加 "platform" 字段,填上你要模拟的 PHP 版本和其他扩展版本。注意:它只覆盖你明确写的项,没写的仍以真实环境为准。
{
"require": {
"php": "^8.1"
},
"config": {
"platform": {
"php": "8.1.25",
"ext-gd": "8.1.25",
"ext-mbstring": "8.1.25"
}
}
}
-
"php": "8.1.25"是最常用项,强制 Composer 当前项目“运行在 PHP 8.1.25” - 扩展如
ext-gd、ext-curl也可指定,尤其当某些包检查扩展版本时(比如symfony/polyfill的部分逻辑) - 执行
composer update --lock才会重新解析依赖并更新composer.lock;仅install不会触发重解析 - 如果误配了不存在的扩展名(如
"ext-foo"),Composer 会警告但继续运行
容易踩的坑和注意事项
platform 是个“静态快照”,它不验证你本地是否真有对应扩展,也不阻止你运行时调用不存在的函数。它只管依赖安装环节。
立即学习“PHP免费学习笔记(深入)”;
- 别在
platform里写比require.php更低的版本(比如require要^8.2,却设platform.php为8.1.0),Composer 会直接报错退出 -
platform对require-dev同样生效,所以测试工具(如phpunit)也会按这个 PHP 版本选兼容版本 - 团队协作时,这个配置必须提交进 Git,否则每人本地环境不同,
composer.lock可能反复变动 - PHP 主版本升级(如从 8.1 → 8.2)时,记得同步更新
platform和require.php,漏掉一个就可能锁住旧版依赖
platform 往往是最容易被忽略的兼容性开关——它不报错、不抛异常,只悄悄让依赖变“老”,直到上线才暴露问题。











