共享主机上Composer临时文件冲突本质是多用户共用系统/tmp目录所致,须通过--tmp-dir=.composer-tmp和--cache-dir=.composer-cache强制指定项目内私有临时目录,并确保构建与线上PHP版本一致。

共享主机上 Composer 临时文件冲突,本质不是“文件被占用了”,而是多个用户/进程共用同一系统级 tmp 目录(如 /tmp),导致 composer install 在本地构建时写入的缓存、zip 解压临时目录被其他账户进程干扰或清理 —— 但你根本没法改服务器的 /tmp 权限,所以必须绕开它。
为什么 shared hosting 的 /tmp 会出问题
多数 cPanel/CloudLinux 主机把 /tmp 设为 noexec,nosuid,且启用 per-user /tmp 隔离(如 /tmp/phpXXXXXX),但 Composer 默认仍尝试在全局 /tmp 下创建子目录。一旦两个用户几乎同时运行 composer install,或某个 cron 清理了 /tmp 中“过期”目录(哪怕刚建好),就会报:
file_put_contents(/tmp/composer_archive_abc123.zip): failed to open stream: No such file or directoryCould not delete /tmp/composer_tmp_xxx: Permission denied- 解压中途中断,
vendor/缺文件但无明确错误
这不是 Composer bug,是共享环境资源复用的必然结果。
强制指定私有临时目录(最稳方案)
不依赖系统 /tmp,让 Composer 把所有中间产物全塞进你自己的项目目录下。操作分两步:
- 在项目根目录创建空目录:
mkdir -p .composer-tmp - 执行安装时显式传参:
composer install --no-dev --optimize-autoloader --cache-dir=.composer-cache --tmp-dir=.composer-tmp
注意:--tmp-dir 是 Composer 2.2+ 才支持的参数;低于此版本需改环境变量:
COMPOSER_CACHE_DIR=.composer-cache COMPOSER_TMP_DIR=.composer-tmp composer install --no-dev --optimize-autoloader
这样所有 zip 下载、解压、缓存都限定在项目内,上传后也无需额外清理。
vendor/ 上传后仍报 Class not found?检查 autoloader 路径是否被 tmp 干扰过
即使你本地用私有 --tmp-dir 成功生成了 vendor/,上传后报错,大概率是因为:autoload_static.php 或 autoload_classmap.php 里硬编码了你本地构建时的绝对路径(比如 /home/user/project/.composer-tmp/xxx)。这类路径不会出现在最终代码里,但会悄悄混进生成的 autoloader 文件中。
- 打开
vendor/autoload.php,搜索.composer-tmp或你的本地用户名路径 —— 如果存在,说明构建时没彻底隔离 - 解决办法:删掉整个
vendor/和composer.lock,用目标主机同版本 PHP(例如 PHP 8.1)重新跑一遍composer install --no-dev --optimize-autoloader --tmp-dir=.composer-tmp - 关键点:构建环境 PHP 版本必须和线上一致,否则 autoloader 生成逻辑不同,可能残留调试路径
别信“chmod 777 /tmp”的临时解法
有些教程让你在共享主机上手动 chmod 777 /tmp,这在绝大多数现代主机上根本不可行 —— CloudLinux 会拦截,cPanel 会重置权限,甚至触发安全告警。更糟的是,即使短时间生效,也会让其他用户的临时文件暴露在你的进程下,违反主机商 TOS,可能导致账户被暂停。
真正有效的隔离,从来不是抢系统资源,而是放弃对 /tmp 的幻想,把临时行为收束到自己可控的目录里。只要 --tmp-dir 和 --cache-dir 指向项目内路径,且构建 PHP 版本与线上一致,就不再有“临时文件冲突”这回事 —— 因为你根本没用到共享的临时区。


















