Composer 2.0+ 唯一有效控制 vendor 安装路径的方式是环境变量 COMPOSER_VENDOR_DIR;config.vendor-dir 已彻底废弃,设了会触发警告且被忽略;COMPOSER_CACHE_DIR 和 COMPOSER_TMPDIR 分别管理缓存与临时解压,三者互不覆盖。

Composer 没有“下载路径目录”这个概念——你真正能控制的只有三个独立路径:缓存目录(cache-dir)、临时解压目录(COMPOSER_TMPDIR)、最终安装目录(vendor/)。混用这三个概念是绝大多数路径问题的根源。
为什么 config.vendor-dir 在 Composer 2.0+ 中完全失效
它不是“偶尔不生效”,而是被彻底移除。你在 composer.json 里写 "vendor-dir": "libs",Composer 会照常安装、但无视该字段,并抛出明确警告:The "config.vendor-dir" option is deprecated, use the "COMPOSER_VENDOR_DIR" environment variable instead. 这意味着:
- 旧教程里的 JSON 片段在当前版本属于无效配置
-
composer diagnose会直接标红提示该配置已废弃 - 哪怕
vendor目录不存在,它也不会按你写的路径创建
真正可控的 vendor 安装路径:只认 COMPOSER_VENDOR_DIR
这是 Composer 2.0+ 唯一官方支持、全命令生效(install/update/require 都走)的方式。它不依赖项目配置是否存在,也不触发弃用警告。
- Linux/macOS 临时使用:
COMPOSER_VENDOR_DIR=third-party composer install - Windows PowerShell:
$env:COMPOSER_VENDOR_DIR="third-party"; composer install - 永久生效:加进
~/.zshrc(或对应 shell 配置)并source,或设为系统环境变量 - 路径必须是相对路径(如
third-party)或绝对路径(如/opt/myapp/deps),不能写成/third-party(伪绝对路径在 Windows 下解析异常)
COMPOSER_CACHE_DIR 和 COMPOSER_TMPDIR 的分工与陷阱
这两个变量常被误认为是“下载路径”,其实它们管的是不同阶段:
-
COMPOSER_CACHE_DIR:只存已下载的 ZIP 包、元数据(packages.json等),不影响网络请求本身。优先级高于composer config --global cache-dir,但仅 Composer 2.2+ 完全支持;2.1.x 及更早版本会忽略它 -
COMPOSER_TMPDIR:只用于下载中临时存放、解压 ZIP、提取文件等过程,不控制 vendor 或 cache 的最终位置。设了但没权限、路径不存在、或用了sudo导致用户错位,就会卡在mkdir(): Permission denied - 三者互不覆盖:改了
COMPOSER_CACHE_DIR不影响COMPOSER_VENDOR_DIR,反之亦然
改完路径后 autoload 和 bin 报错,根本原因不是路径没改对
这是最常被忽略的一环:COMPOSER_VENDOR_DIR 只负责把包装到哪,不会自动修复你的代码引用、脚本调用或 IDE 设置。
-
require 'vendor/autoload.php'必须同步改成require 'third-party/autoload.php' - 脚本里调用
vendor/bin/phpunit得改成third-party/bin/phpunit - IDE(如 PhpStorm)可能缓存了旧
vendor路径,需手动刷新索引或重置项目设置 - 如果你用符号链接方案(
ln -s /shared/vendor ./vendor),注意 CI/CD 中 Windows Git Bash 不支持 symlink,Docker 容器内需挂载对应路径


















