composer check-platform-reqs只校验composer.json中显式声明的PHP版本和扩展是否在当前CLI环境中可用,未声明则不检查;报missing但php -m可见zip,通常因Composer与php命令调用不同PHP二进制文件。

composer check-platform-reqs 不是“检测所有环境需求”的万能命令,它只校验 composer.json 里**显式写死的 PHP 版本和扩展声明**是否在当前 CLI 环境中可用。没写 = 不查,写了但扩展没加载 = 报 missing,而你看到的 php -m 结果,很可能根本不是 Composer 正在用的那个 PHP。
为什么 check-platform-reqs 显示 ext-zip missing,但 php -m 能看到?
这不是扩展没装,是 Composer 和你执行 php -m 时调用的不是同一个 PHP 二进制文件。
- 运行
which php查当前 shell 默认 PHP 路径,再用它执行/usr/bin/php -m | grep zip或/opt/homebrew/bin/php -m | grep zip—— 必须路径完全一致 - macOS 上 Homebrew 安装的 PHP 常被系统自带旧版(不带 zip)覆盖 PATH;
php -v看到的是新版本,但 Composer 启动时可能用的是/usr/bin/php - Linux 下 apt 包和源码编译的 PHP,
.so文件路径不同,CLI 和 Web SAPI 加载的扩展也各自独立
check-platform-reqs --lock 和不加 --lock 有啥区别?
不加 --lock:只读 composer.json 的 require 和 config.platform,检查你“想装什么”;加了 --lock:直接按 composer.lock 里记录的**实际已安装包版本**反推环境要求,检查你“已经装了什么、它们到底要啥”。
- 某包 v2.4.0 不需要
ext-gmp,但 v2.5.0 加了硬依赖 → 不加--lock不会报,加了就会暴露 - CI/CD 部署前必须加
--lock,否则上线后可能突然报Call to undefined function gmp_init() -
composer install --dry-run会模拟完整安装流程(耗时、依赖网络),而check-platform-reqs --lock是纯静态比对,毫秒级完成
怎么让 check-platform-reqs 真正有用,而不是走个过场?
关键不是多跑几遍命令,而是先规范声明需求,再用对工具验证。
- 在
composer.json的require里补全最低 PHP 版本:"php": ">=8.1.0"(别用^8.1,check-platform-reqs对范围符支持弱) - 显式列出项目硬依赖的扩展:
"ext-zip": "*"、"ext-pdo_mysql": "*"、"ext-mbstring": "*" - 本地开发建议禁用
config.platform;它适合 CI 中模拟目标环境(如"php": "8.2.10"),但会掩盖真实兼容问题 - Web 环境务必单独打开
phpinfo()页面确认扩展是否启用——CLI 过了 ≠ 网页能跑
真正容易被忽略的是:check-platform-reqs 只告诉你“声明的约束是否满足”,不是“代码能不能跑”。它不扫描 PHP 源码,不检查 conflict 或 provide 字段,也不管底层库(比如 ext-intl 缺 ICU)、INI 设置(如 memory_limit)或运行时功能是否正常。



















