composer diagnose检查Composer自身运行环境是否安全,仅验证基础连通性、权限及配置合法性;composer check-platform-reqs则校验项目声明的PHP版本与扩展是否满足require约束,二者职责不同、不可替代。

直接运行 composer diagnose 和 composer check-platform-reqs 就能覆盖 80% 的环境兼容性问题,但两者职责完全不同:前者查“Composer 能不能安全工作”,后者查“你写的依赖能不能真装上”。混用或跳过任一环节,都可能在 CI 或上线时突然失败。
composer diagnose 只做基础连通性检查
它不验证 PHP 版本、不解析 require 字段、也不管扩展是否被代码实际调用——只确认 Composer 自身运行链路是否通畅。
- 会报错的典型场景:
[FAIL] openssl extension not loaded(php.ini没启用)、[FAIL] vendor directory is not writable(权限归属错,比如 root 写的,www-data 读不了)、[FAIL] GitHub API is not working(token 过期或限流,curl -I https://api.github.com/rate_limit看X-RateLimit-Remaining是否为 0) - 不会报错但很危险的情况:
composer.json里写了"php": "^8.2",本地却是 PHP 8.1 ——diagnose完全不拦,等install后运行时报ParseError才暴露 - 必须在项目根目录运行;如果提示
No composer.json present,先cd对路径,别急着重装 Composer
composer check-platform-reqs 验证的是你声明的依赖
它只读 composer.json 的 require 和 require-dev 字段,逐条比对当前 PHP 版本、已加载扩展是否满足约束。漏声明 = 漏检查。
- 常见误判:
check-platform-reqs报ext-zip: * (missing),但php -m | grep zip看得见——根本不是没装,是 Composer 调用的 PHP CLI 二进制和你终端敲的不是同一个;用which php和composer config --global bin-dir对齐路径,再用完整路径如/opt/homebrew/bin/php -m复现 -
"platform"配置会覆盖真实环境:"platform": {"php": "8.1"}会让check-platform-reqs检查“假装的 8.1”,而非你本地的 8.2;CI 中有用,本地开发建议删掉,否则掩盖真实兼容风险 - 它不扫描代码里实际调用的函数,比如某包在
src/里用了openssl_encrypt()却没在composer.json声明"ext-openssl": "*",这个检查就完全绕过
真正暴露运行时兼容问题的只有 install + 测试
check-platform-reqs 通过 ≠ 项目能跑;diagnose 通过 ≠ 依赖能装。最终防线是让代码动起来。
- 加
--dry-run不够:它只模拟解析,不加载 autoloader,更不触发扩展调用;composer install --dry-run成功后,仍可能在require 'vendor/autoload.php'时因语法错误(如 PHP 8.0 的联合类型)直接崩溃 - 推荐组合动作:
composer install --no-dev && php -l $(find src -name "*.php" | head -n 20)快速扫语法;再跑php -r "require 'vendor/autoload.php';"看是否抛出ParseError或Extension not found - 依赖包自身用了高版本语法?用
composer show vendor/package查安装版本,再对照其 CHANGELOG 确认是否支持你的 PHP 版本;不要指望 Composer 自动降级,它只按你写的约束选包
最容易被忽略的一点:所有检查都依赖你当前使用的 PHP CLI 二进制。PATH、Docker、Homebrew、XAMPP、手动编译……多个 PHP 共存时,php -v、composer、IDE 内置终端、Web Server(如 Apache 的 libphp.so)可能各自调用不同版本。验证前,先统一确认路径,否则所有检查结果都是无效的。











