必须在 composer.json 的 config.platform.php 中显式声明目标 PHP 版本(如 "8.0.30"),否则 Composer 会按运行环境判断兼容性,导致 CI 或低版本服务器 install 失败;修改后需执行 composer update --lock 同步 composer.lock 中的 platform 声明。

composer.json 里必须配 config.platform
PHP 8.0 项目在 CI 或低版本服务器上 install 失败,常见原因是依赖包声明了 "php": "^8.0",但构建机实际是 PHP 7.4 —— Composer 默认按运行环境判断 platform 兼容性,不是按你项目目标 PHP 版本。
解决方法是在 composer.json 的 config 段显式锁定目标平台:
{
"config": {
"platform": {
"php": "8.0.30"
}
}
}
这样 composer install 就会忽略当前 PHP 版本,只按你声明的 8.0.30 解析依赖。否则某些要求 php >=8.0.0 的包(比如 symfony/console:^6.0)会被跳过或报错。
- 别写
"php": "8.0"—— 这会匹配所有 8.0.x,但部分包可能要求具体补丁版本 - 生产部署前务必用
php -v核对服务器真实版本,config.platform.php必须 ≤ 实际版本,否则运行时可能出致命错误 - 如果项目需同时支持 PHP 8.0 和 8.1,
config.platform.php应设为"8.0.0",靠依赖自身的版本约束来兼容
composer.lock 的 platform 字段要和 config.platform 一致
composer.lock 文件顶部有个 platform 块,它是在首次 composer install 或 update 时自动生成的,内容来自当前环境或 config.platform。如果两者不一致,会导致不同机器上解析出不同依赖树。
立即学习“PHP免费学习笔记(深入)”;
现象:本地 composer install 装了 doctrine/annotations:1.13,CI 上却装了 1.12,只因 lock 文件里 platform 写的是 "php": "8.1.0",而 CI 环境没设 config.platform。
- 每次修改
config.platform.php后,必须执行composer update --lock刷新 lock 文件中的 platform 声明 - Git 提交前检查
composer.lock里的platform是否和composer.json里的一致,不一致说明有人漏跑了 update - GitHub Actions 中建议加一步:
grep -q '"php": "8.0' composer.lock || exit 1,防误提交
require-dev 里的工具也要考虑 PHP 8.0 兼容性
开发依赖如 phpunit/phpunit、laravel/pint 同样受 config.platform 影响。PHP 8.0 下 phpunit/phpunit:^9.5 是安全的,但 ^10.0 要求 PHP 8.1+ —— 如果没锁 platform,composer update 可能悄悄升到不兼容版本。
-
composer require --dev phpunit/phpunit:^9.5显式指定兼容范围 - 避免把
roave/security-advisories放进require—— 它只做安装时校验,必须放require-dev,且它的版本本身也需匹配 PHP 8.0 - 本地跑
phpunit报ParseError: syntax error, unexpected token "string"?大概率是装了 PHP 8.1+ 才支持的语法特性,回退 PHPUnit 版本或检查 platform 配置
vendor/autoload.php 加载失败常因 platform 不匹配
PHP 8.0 项目上线后报 Class not found,但 vendor/autoload.php 存在、路径也没错 —— 很可能是某个依赖在 PHP 8.0 下无法生成有效 autoload map,原因通常是该依赖的 composer.json 声明了 "php": "^8.1",而你的 config.platform 没生效或写错了。
- 执行
composer show vendor/package-name查看该包声明的 PHP 要求 - 用
composer depends vendor/package-name找出谁把它拉进来,再顺藤摸瓜看是否 platform 锁定失效 - 临时验证:删掉
vendor和composer.lock,只留composer.json,重新composer install—— 如果成功,说明旧 lock 文件已过期或 platform 不一致
config.platform 就万事大吉。它只影响依赖解析阶段,不改变运行时行为;真正出问题往往发生在 lock 文件未同步、或某条 require-dev 没被 platform 约束住的时候。



















