Composer 严格依赖 shell 中 php 命令指向的 CLI 版本,与 Web 服务器或 IDE 配置无关;若 php -v 与 Composer 实际所用版本不一致,主因是 shell 缓存、PATH 顺序错误或未强制重链接(如 macOS brew link --force),应通过 which php、ls -l $(which php) 和 composer --version 中的 PHP 字段交叉验证,并优先使用绝对路径调用目标 PHP 二进制执行 Composer。

php -v 显示的版本和 Composer 实际用的不一致
Composer 完全依赖 shell 中 php 命令指向的二进制,不是你 Web 服务器用的版本,也不是 IDE 里配置的版本。常见现象是:终端敲 php -v 看着是 8.2,但 composer install 仍报 Your PHP version 7.4.33 does not satisfy that requirement。
原因通常是 shell 缓存或 PATH 顺序错乱:
- Linux/macOS 没执行
hash -r,shell 还记着旧的php路径 - Windows 的 PATH 里旧版 PHP 目录(如
C:\xampp\php)排在新版之前 - Mac 上 Homebrew 切换后没
brew link --force php@8.2,which php仍指向 /usr/bin/php
验证方式:运行 which php 和 ls -l $(which php),看真实路径;再对比 composer --version 输出里的 “PHP” 字段(它会显示 Composer 当前绑定的 PHP SAPI)。
多 PHP 版本共存时,让 Composer 固定用某一个
别改系统默认 PHP,尤其在 CI 或多人协作项目里。直接调用目标 PHP 二进制最稳:
立即学习“PHP免费学习笔记(深入)”;
- Linux/macOS:
/usr/bin/php8.2 /usr/local/bin/composer install - Windows:
"C:\php-8.2\php.exe" composer.phar install - Docker 构建中:
RUN /usr/bin/php8.2 /tmp/composer.phar install
这样绕过 shell 的 php 命令查找逻辑,彻底隔离版本。CI 脚本里务必前置 php -v 打日志,否则失败时根本看不出用的是哪个 PHP。
config.platform.php 不是“降级开关”,别乱设
config.platform.php 只影响依赖解析阶段,它不会让 PHP 7.4 运行 PHP 8.2 的语法。滥用后果很直接:装进 vendor 的包含 match 表达式,一跑就 ParseError: unexpected token "match"。
只在两种场景下设它:
- 你在 PHP 7.4 开发机上,但要为 PHP 8.2 生产环境打包,且所有包已验证兼容
- CI 流水线明确指定目标 PHP 版本(如 GitHub Actions 的
php-version: 8.2),且 lock 文件由该环境生成
设置后必须跟 composer update --lock,否则 composer.lock 里还存着旧平台选的包版本。这个配置写进 composer.json 后,别提交到团队仓库——除非所有人 PHP 版本完全一致。
删 vendor 和 composer.lock 为什么还是报错
因为冲突根源不在缓存,而在环境没对齐。删了重装只是用当前 php 命令再跑一遍解析逻辑。如果 php -v 还是错的,或者 composer.json 里 "require": {"php": "^8.1"} 没动,报错必然重现。
真正要检查的三处是:
-
php -v第一行输出(CLI 版本) -
composer.json中require.php和config.platform.php是否冲突或错配 - CI 或 Dockerfile 里是否漏写了 PHP 版本安装/切换步骤(比如 GitHub Actions 忘了
setup-phpaction)
复杂点在于:Web SAPI 和 CLI 版本可以不同,而 Composer 只认 CLI;Docker 构建阶段和运行阶段的 PHP 也可以不同,但 composer install 发生在构建期——这点最容易被忽略。



















