platform配置不改变本地PHP版本和运行时行为,仅在composer install/update阶段按声明的PHP版本及扩展选包;必须写在composer.json根级platform字段(与require同级),不可嵌套于config内,且需手动列全ext-*扩展。

platform 配置不改变你本地的 PHP 版本,也不影响代码运行时行为;它只在 composer install 和 composer update 阶段,强制 Composer 按你声明的 PHP 版本和扩展来选包。
platform 必须写在 composer.json 根级,不是 config.platform
很多人卡在这一步:把 platform 塞进 "config": { "platform": { ... } } 里,结果完全不生效。原因很直接——Composer 只认根级 platform 字段,和 require、autoload 同级。
正确写法示例:
{
"require": { "monolog/monolog": "^2.0" },
"platform": {
"php": "8.1.25",
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-json": "*"
}
}
错误写法包括:
-
config.platform(不存在该路径,会被忽略) - 全局配置
composer config -g platform.php 8.1(污染个人环境,CI 不识别) - 单独建
platform.php文件(Composer 完全不读)
验证是否生效:运行 composer config --list | grep platform,有输出且带 (local) 才算对。
只写 "php": "8.1" 不够,扩展必须手动列全
Composer 不扫描你本地 php.ini,它只看你 platform 里明确写的项。漏掉一个扩展,就可能让 composer install 报错中断。
常见必须补全的扩展:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
"ext-mbstring": "*"(Laravel、Symfony 等大量依赖) -
"ext-openssl": "*"(HTTP 客户端、JWT、Composer 自身更新) -
"ext-json": "*"(几乎所有现代 PHP 包都 require) -
"ext-sodium": "*"(密码学相关,PHP 7.2+ 默认启用,但必须声明) -
"ext-pdo": "*"(数据库驱动基础,哪怕你用 MySQLi 也建议加上)
注意:ext-xxx 是固定前缀,不能写成 php-xxx 或 xxx;版本填 * 可行,但填具体值(如 "8.1.25")更稳妥,避免某些包的版本校验逻辑误判。
--ignore-platform-reqs 是危险开关,不是替代方案
看到 Your requirements could not be resolved 就加 --ignore-platform-reqs?这等于关掉所有兼容性检查——Composer 会照单全收 PHP 8.3 才有的语法、函数或类,部署到 PHP 8.1 服务器上直接 Fatal error: Uncaught Error: Call to undefined function。
它只适合临时验证问题是否出在 platform 配置本身,用完立刻删掉。CI/CD 构建中绝对禁用。
真正该做的是:
- 登录生产服务器,运行
php -v和php -m - 把输出结果逐条映射到
platform字段里 - 确认每个
require的包在目标 PHP 版本下确实有兼容版本(可用composer show vendor/package --all查)
platform 不解决运行时缺失扩展的问题
你设了 "ext-redis": "*",Composer 就允许安装 predis/predis 或 phpredis,但它不会帮你装 Redis 扩展,也不会让 new Redis() 在没扩展的机器上跑起来。
容易被忽略的关键点:
- 它只影响依赖解析,不影响
php -v输出,也不影响extension_loaded('redis')的返回值 - 如果代码里直接调用了
Redis::connect(),而服务器没装 ext-redis,照样报Class 'Redis' not found - 真正安全的做法是:把强依赖扩展的功能做运行时检测 + fallback(比如缓存驱动可切换为 file),而不是靠 platform “假装存在”

















