正确写法是php -d memory_limit=2G composer install,因-d是PHP解释器参数,必须置于composer命令前;COMPOSER_MEMORY_LIMIT环境变量更精准但仅作用于Composer内部逻辑,且不可设在.env等文件中。

php -d memory_limit 参数必须写在 composer 命令前面
很多人把 php -d memory_limit=2G 放在 composer install 后面,或者漏掉 php 直接跑 -d memory_limit=2G composer install,结果完全不生效。这是因为 -d 是 PHP 解释器的启动参数,只对紧随其后的 PHP 脚本起作用。
正确写法是:
-
php -d memory_limit=2G composer install(Linux/macOS/CMD) -
php -d "memory_limit=-1" composer update(PowerShell 中引号不能少) -
php -d memory_limit=2G ./composer.phar install(用 .phar 文件时,不能省略php)
等号两边不能有空格,2G 会被 PHP 自动转为字节数;-1 表示无限制,本地调试可用,CI 环境建议写死为 2G 或 3G 防止被 OOM killer 杀掉。
COMPOSER_MEMORY_LIMIT 环境变量优先级更高但只管 Composer 自身逻辑
这个变量是 Composer 原生识别的,它不改 PHP 的全局内存限制,只影响 Composer 内部的依赖解析、SAT 求解、脚本执行等关键阶段,更精准、副作用更小。
设置方式分场景:
- 临时生效(当前终端):
export COMPOSER_MEMORY_LIMIT=2G(Linux/macOS)或set COMPOSER_MEMORY_LIMIT=2G(Windows CMD) - CI 脚本中推荐直接前置:
COMPOSER_MEMORY_LIMIT=2G composer install --no-interaction - 验证是否生效:
php -r "echo getenv('COMPOSER_MEMORY_LIMIT');"应输出2G
注意:它对 composer dump-autoload 也生效,但该命令本身内存压力不大,一般不需要调;别往 .env 或 phpunit.xml 里塞这个变量——Composer 不读这些文件。
为什么改 php.ini 经常白忙活
PHP CLI 和 Web 服务(如 PHP-FPM、Apache mod_php)通常加载不同的 php.ini 文件。你改了 Apache 的配置,对终端里跑的 Composer 完全没影响。
先确认 CLI 用的是哪个配置:
- 运行
php --ini,看 “Loaded Configuration File” 对应路径(常见如/etc/php/8.2/cli/php.ini) - 改完后验证:
php -r "echo ini_get('memory_limit');"输出应为2147483648或2G - Docker、GitHub Actions、GitLab CI 等环境基本不允许改
php.ini,硬改会失败或被覆盖
全局调高 memory_limit 还有风险:一个失控的 Web 脚本可能吃光整台服务器内存,所以不建议线上长期设为 -1。
Resolving dependencies 卡住 ≠ 网络慢,很可能是内存不够
这个阶段完全不走网络,但会高频扫描 vendor/ 和项目目录下的 PHP 文件,构建类映射、校验哈希、执行插件逻辑。一旦内存不足,Composer 就会反复重试、静默崩溃,甚至被系统直接 kill(日志只剩 Killed)。
排查和缓解建议:
- 关掉
xdebug:运行php -v看是否含xdebug,有的话临时禁用,比如php -d xdebug.mode=off composer install - 删掉
dev-dependencies:加--no-dev可降低一半以上内存消耗,CI 构建必须加 - 检查 autoload 配置:确认
composer.json的autoload和autoload-dev没把node_modules/、dist/、logs/这类非代码目录包含进去 - 清缓存再试:
composer clear-cache,损坏的缓存有时会触发异常解析逻辑
真正棘手的是老插件(比如已废弃的 fxp/composer-asset-plugin)或低版本 Composer/PHP,它们在依赖树解析时内存峰值翻倍,这种时候光调内存只是治标,升级才是根因解法。











