require.php 声明项目运行所需 php 最低及可选上限版本,如 "php": "^8.1" 表示 ≥8.1.0;config.platform.php 则用于构建时“伪装”php版本,绕过本地环境限制。

composer.json 里怎么写 PHP 版本约束
直接在 composer.json 的 config.platform.php 或根级 require.php 中声明,二者作用完全不同:require.php 是项目运行所依赖的 PHP 最低(及可选上限)版本,Composer 会据此筛选兼容的包;config.platform.php 是“假装”当前环境是某个 PHP 版本,用于构建或 CI 场景下绕过本地真实版本限制。
常见写法:
-
"require": { "php": "^8.1" }—— 要求运行环境 PHP ≥8.1.0 且 "require": { "php": ">=8.0, —— 更明确的区间,兼容性更强-
"config": { "platform": { "php": "8.0.0" } }—— 构建时让 Composer 忽略你本机的 PHP 8.2,只按 8.0 解析依赖
为什么 require.php 不生效?常见失效场景
最常踩的坑是:改了 require.php 但 composer install 没报错,甚至装上了本不该兼容的包。原因通常是:
- 已存在
composer.lock,Composer 优先按 lock 文件还原,不会重新校验 PHP 版本约束 - 你本地 PHP 版本满足旧约束,而新约束更严格,但 lock 文件没更新,Composer 就不检查
- 用了
composer update --with-all-dependencies却没加--ignore-platform-req=php,导致误触发平台检查中断流程
解决办法:改完 require.php 后,必须删掉 composer.lock 再跑 composer install,或强制重解: composer update --lock。
立即学习“PHP免费学习笔记(深入)”;
config.platform.php 和 require.php 混用时的优先级
两者不是叠加关系,而是分层控制:require.php 定义“这个项目理论上需要什么 PHP”,config.platform.php 定义“我现在想模拟成什么 PHP 来跑安装”。当二者冲突时,config.platform.php 会覆盖本地真实 PHP 版本,但不会绕过 require.php 的语义检查——也就是说,如果你写 "require": { "php": "^8.2" },又设 "platform": { "php": "8.0.0" },Composer 会直接报错:Your platform version '8.0.0' does not satisfy the required version '^8.2'。
真正安全的混用方式只有两种:
- 降低
require.php下限,再用platform.php模拟更低版本做兼容测试 - 仅在 CI 配置中用
platform.php固定构建环境,开发时靠require.php约束底线
PHP 版本约束对依赖解析的实际影响
它不只是个提示——它会实质性改变 composer update 拿到的包版本列表。比如 monolog/monolog 在 PHP 8.0+ 默认装 v3.x,但在 "php": "^7.4" 下就只能装 v2.9.x;再比如 laravel/framework v11 要求 PHP ≥8.2,若你的 require.php 是 ^8.1,Composer 就根本不会考虑 v11,哪怕它已发布。
验证方法很简单:composer prohibits php:8.2 可列出所有因 PHP 8.2 不兼容而被排除的包;composer show --platform 则显示当前生效的平台版本(含 platform.php 覆盖结果)。
最易被忽略的一点:Docker 多阶段构建中,build 阶段和 runtime 阶段的 PHP 版本可能不同,config.platform.php 往往只在 build 阶段起作用,而 require.php 才决定最终镜像能否运行——别只测构建成功就以为万事大吉。











