不能直接共用 vendor 目录,因不同项目依赖同一包的不同版本会导致类冲突;符号链接需依赖树完全一致(含 composer.lock、platform 配置),并禁用脚本与插件,且 autoload.php 的硬编码路径需特殊处理。

为什么不能直接共用 vendor 目录
Composer 默认为每个项目生成独立的 vendor 目录,因为不同项目可能依赖同一包的不同版本(比如 monolog/monolog v2.9 和 v3.5),强行共享会触发 Class not found 或 Cannot declare class 错误。符号链接方案本质是“欺骗” Composer 让它以为 vendor 在本地,实际指向统一位置——但前提是所有项目使用完全一致的 composer.json 依赖树(包括版本约束、平台配置、插件启用状态)。
用 composer install --no-scripts --no-plugins 避免执行钩子冲突
多个项目共用 vendor 时,post-install-cmd 等脚本可能互相干扰(例如重复生成 autoload 文件、修改缓存路径)。必须禁用自动执行:
-
--no-scripts:跳过所有scripts定义的命令 -
--no-plugins:防止插件(如hirak/prestissimo)在不同项目间污染全局行为 - 首次安装需在「主 vendor 目录」所在项目中运行完整命令,其他项目只做符号链接 +
composer install --no-scripts --no-plugins
创建符号链接前先统一 composer.lock
符号链接生效的前提是所有项目最终解析出完全相同的依赖树。这意味着它们的 composer.lock 必须一致(不只是 composer.json):
- 选一个权威项目作为 lock 源,运行
composer update --lock生成标准composer.lock - 把该文件复制到其他项目根目录,覆盖原有
composer.lock - 确保所有项目
composer.json中的platform配置(如"php": "8.1.0")完全相同,否则composer install会重新计算依赖 - 检查
composer show --tree输出是否一致,不一致说明平台或约束有隐性差异
用 ln -sf 创建跨项目 vendor 链接(Linux/macOS)
假设你选定 /opt/composer-shared/vendor 为共享目录,各项目位于 /var/www/project-a、/var/www/project-b:
立即学习“PHP免费学习笔记(深入)”;
cd /var/www/project-a rm -rf vendor ln -sf /opt/composer-shared/vendor vendor cd /var/www/project-b rm -rf vendor ln -sf /opt/composer-shared/vendor vendor
Windows 用户需改用 mklink /D,且必须以管理员权限运行命令提示符;注意 PHP 进程需有读取目标目录的权限,Apache/Nginx 用户组要能访问 /opt/composer-shared。
真正麻烦的是 autoload 机制:Composer 自动生成的 vendor/autoload.php 里硬编码了 __DIR__ 路径,链接后会导致 require 加载错位。解决方案是——不要让项目直接 require 链接后的 autoload.php,而是统一用共享目录下的入口,或改用 composer dump-autoload --optimize --classmap-authoritative 减少路径依赖。











