必须在require中写"php": "^8.0",因其是唯一被Composer和Packagist一致识别、能正确排除PHP 7.x的写法;"8.0.*"会被忽略,">=8.0.0"可能因工具链解析偏差漏判,且必须置于require而非require-dev,否则不参与主依赖选型。

require.php 必须写成 "php": "^8.0",不能用 "8.0.*" 或 ">=8.0.0"
Composer 对 PHP 版本的语义解析依赖于标准的 SemVer 范围语法。"^8.0" 是唯一被 Packagist 和 Composer 依赖求解器一致识别、且能正确排除 PHP 7.x 的写法。写成 "8.0.*" 会被当作模糊通配,部分旧版 Composer(如 2.2 以下)可能忽略;">=8.0.0" 虽然逻辑等价,但某些插件或 CI 工具链在解析时会因正则匹配偏差漏判。
常见错误现象:composer install 在 PHP 7.4 下静默成功,但后续运行时报 ParseError: syntax error, unexpected token "match"——说明约束没生效。
- 必须放在
require段,而非require-dev:dev 段的php只影响 PHPUnit、PHPStan 等工具,不参与主依赖选型 - 若项目用了 PHP 8.2+ 特性(如
readonly class),就得升为"php": "^8.2",不能为了“兼容”降级声明 -
composer update会校验该字段;但已有composer.lock时,composer install默认跳过重解析,所以升级 PHP 要求后务必跑一次composer update --lock
CI/CD 中要装出真正兼容 PHP 8.0 的包,得靠 config.platform.php 模拟
本地开发用 PHP 8.2,但线上跑的是 PHP 8.0?只靠 require.php 不够。Composer 默认以你当前 PHP 版本(8.2)为平台去挑包,可能选中依赖 str_contains() 的 monolog/monolog:^3.0,而它实际只兼容 8.1+。
解决办法是在 composer.json 里加 platform 配置:
立即学习“PHP免费学习笔记(深入)”;
{
"config": {
"platform": {
"php": "8.0.30"
}
}
}
注意:"php": "8.0.30" 必须写具体小版本号,"^8.0" 或 "8.0" 都无效;它优先级高于真实环境,但低于 require.php 的语义边界。
- CI 启动时执行
composer config platform.php 8.0.30也可临时覆盖,但需紧接composer install --no-dev --platform=php:8.0.30 --no-plugins -
--no-plugins很关键:某些插件(如 composer-unused)会绕过 platform 模拟,导致装错包 - 这个配置只影响依赖解析,不改变实际运行环境;上线前仍需在真实 PHP 8.0 容器里跑完整测试
为什么 composer install 有时不报错,即使 PHP 版本不满足?
不是约束失效,而是触发条件未满足。Composer 的 PHP 校验只在两个环节发生:一是 composer install 读取 composer.lock 前比对本地 PHP 与 require.php;二是 composer update 重新解析依赖时。
典型静默场景:
- 已有
composer.lock,且其中记录的包版本是在旧 PHP(如 8.0)下解析成功的 →composer install直接按 lock 安装,跳过校验 - CI 环境设置了
COMPOSER_IGNORE_PLATFORM_REQS=1或用了--ignore-platform-reqs→ 所有平台约束(包括php、ext-gd)全被忽略 - Composer 实际运行的 PHP 版本 ≠ 你认为的那个:比如系统有多个 PHP,
which composer显示 shebang 是#!/usr/bin/env php7.4,此时php -v看到的 8.2 完全无关
验证当前 Composer 绑定的 PHP 版本:运行 composer --version,第一行就带路径;更准的是 head -1 $(which composer)。
composer show --platform 是唯一可信的实时平台视图
它输出的是 Composer 当前「认为」自己运行的平台环境,而不是系统真实版本。如果你改了 config.platform.php,这里必须显示 php: 8.0.30;如果还显示 php: 8.2.5,说明配置没生效或被命令行参数覆盖。
这个命令不依赖 composer.lock,也不受 --ignore-platform-reqs 影响,是调试平台配置是否到位的最终依据。
容易被忽略的一点:platform 配置对扩展(如 ext-gd)同样生效,但必须显式写进 config.platform,否则 Composer 默认认为所有扩展都存在——哪怕你线上没装 ext-redis,只要没声明,它就敢给你装依赖它的包。



















