唯一可靠方式是path仓库配"options":{"symlink":true};composer link仅作用于已安装包,不改lock、不刷新autoload,易被update覆盖,且Windows无权限时静默fallback为copy。

用 path 类型仓库配 "options": {"symlink": true} 是唯一可靠方式;composer link 仅适用于已安装包,且极易被后续 composer update 覆盖,不建议在正式调试流程中使用。
为什么不能直接用 composer link
composer link 只对 vendor 中「已存在」的包生效,本质是创建软链接覆盖原目录,但它不修改 composer.lock,也不刷新 autoload 映射。常见问题包括:
- 执行
composer update后链接被自动还原为远程包副本 - 本地包未提前
composer require安装过,命令直接报错Package not installed - Windows 下默认无权限创建 symlink,静默 fallback 到复制,你以为在改本地代码,实际改的是 vendor 里的副本
- IDE 断点失效:因为 Xdebug 加载的是 vendor/ 下的路径,而你编辑的是源目录,两者路径不一致
path 仓库 + symlink 的正确配置
这是可复现、可协作、支持实时调试的标准做法。关键三步必须同步完成:
- 在主项目
composer.json根层级添加repositories,url必须是相对路径(如"../my-package"),不能以/或./结尾 - 本地包根目录下必须有合法
composer.json,其中name字段要和主项目require中完全一致(大小写、斜杠、连字符逐字匹配) - 在
repositories条目里显式加"options": {"symlink": true},否则 Linux/macOS 默认尝试 symlink,Windows 默认 copy
示例片段:
{
"repositories": [
{
"type": "path",
"url": "../my-package",
"options": {
"symlink": true
}
}
],
"require": {
"my-vendor/my-package": "dev-main"
}
}
执行后怎么验证 symlink 是否生效
别只看 vendor 目录是否存在,要确认它是否真的指向你的本地源码:
- Linux/macOS:运行
readlink vendor/my-vendor/my-package,输出应为完整绝对路径,且指向你配置的url目标目录 - Windows:运行
dir vendormy-vendormy-package,若显示即成功;否则大概率是复制模式(需检查是否以管理员身份运行终端) - 改一行本地包
src/Helper.php,然后在主项目中调用该方法——结果必须立刻变化,否则说明没走 symlink - 运行
php -r "echo class_exists('MyVendor\MyPackage\Helper') ? 'ok' : 'fail';",输出ok表明 autoload 已加载 symlink 目录下的类
调试时最容易忽略的路径陷阱
Xdebug 断点进不去,90% 是因为 IDE 的 path mapping 指向了 vendor/ 下的 symlink 目标,而不是你日常编辑的那个本地包目录。必须手动配平:
- 在 PhpStorm 中:Settings → PHP → Servers → Path Mappings,把
vendor/my-vendor/my-package映射到你本地开发目录(如D:projectsmy-package) - VS Code 中:
launch.json的pathMappings也要同样处理,值必须是本地源码路径,不是 vendor 路径 - 如果本地包用了
autoload-dev,记得运行composer dump-autoload --dev,否则测试类不会被加载 - Git 初始化不是可选项:Composer 在部分版本中会跳过未
git init的目录,不报错也不提示,导致composer update静默失败











