Composer 疯狂往 /tmp 写文件是因为其解压、生成 autoload、运行脚本等操作均依赖 sys_get_temp_dir() 返回的系统临时目录(如 /tmp 或 %TEMP%),该路径由操作系统环境变量 TMPDIR 控制,与 Composer 的 cache-dir 完全无关,且不受 composer.json 配置影响。

Composer 为什么疯狂往 /tmp 写文件?
因为 Composer 在解压 ZIP、生成 autoload 映射、运行脚本时,大量依赖 PHP 的 sys_get_temp_dir() 返回路径——这个路径就是系统级临时目录,Windows 是 C:\Users\用户名\AppData\Local\Temp,Linux/macOS 默认是 /tmp 或由环境变量 TMPDIR 指定。它不走 Composer 自己的 cache-dir,也不受 composer.json 控制,纯看系统配置。
TMPDIR 和 cache-dir 完全不是一回事
很多人以为改了 composer config --global cache-dir 就能管住所有临时文件,其实完全不能:
-
cache-dir只控制下载后的包缓存(.tar.gz或.zip归档),位置可自定义,比如D:\composer-cache -
TMPDIR是操作系统级环境变量,影响所有调用sys_get_temp_dir()的 PHP 进程,包括 Composer 解压时创建的composer_*.zip、php*.phar等一次性临时文件 - 这两个路径可以完全不同,但一旦
TMPDIR所在磁盘爆满,composer install会直接失败,报错却常被误判为“网络超时”或“内存不足”
怎么安全地改 TMPDIR?
修改前先确认当前值:echo $TMPDIR(Linux/macOS)或 echo %TMPDIR%(Windows CMD)。改的时候注意这些点:
- Linux/macOS 推荐临时生效:
TMPDIR="/mnt/fast-ssd/tmp" composer install;永久写入~/.bashrc或/etc/environment,但别污染全局(尤其 CI 环境) - PowerShell 要加引号:
$env:TMPDIR="D:\temp",否则空格或路径含括号会出错 - Windows 上若用 Git Bash,它不读 Windows 的
%TEMP%,必须显式设TMPDIR,否则仍走/tmp(Git Bash 自建的符号链接) - Docker 容器里务必在
docker run时传入:-e TMPDIR=/tmp2 -v /host/tmp2:/tmp2,否则默认/tmp往根分区写,极易撑爆
为什么 TMPDIR 改了还是看到 /tmp 在涨?
常见漏点:
- PHP CLI 和 Web 服务器用不同配置,
php -r "echo sys_get_temp_dir();"输出才是 Composer 实际用的路径,别只信phpinfo() - 某些 CI 平台(如 GitHub Actions)会重置环境变量,需在
steps中每步都显式env:注入,不能只靠 setup-php - Composer 插件(如
hirak/prestissimo)可能绕过标准临时目录逻辑,这类插件已基本废弃,建议禁用 - 没清旧文件:改完
TMPDIR后,原/tmp下残留的composer_*.zip不会自动删,得手动清理
cache-dir 和 TMPDIR 都挪到大硬盘,如果 PHP 进程本身被 xdebug 拖慢,临时文件生命周期变长,堆积速度反而更快——所以关 xdebug 和调 TMPDIR 得一起做。











