composer install 从不创建软链接,因其仅按 composer.lock 还原状态,跳过 repositories 解析;唯有 composer update 会执行完整依赖解析并可能创建软链接。

composer install 为什么从不创建软链接
因为 composer install 的设计目标是「还原 lock 文件记录的状态」,它跳过整个 repositories 解析流程,也不检查本地 path 仓库是否存在、是否可 symlink。哪怕你刚在 composer.json 里加了 path 源,只要 composer.lock 里还存着 Packagist 的 dist URL,它就照旧下载 ZIP 包并解压——根本不会碰你的本地目录。
真正触发 symlink 的唯一时机是依赖解析阶段,也就是 composer update 运行时。这个阶段 Composer 才会读取 repositories、比对本地路径、校验 name 和 Git 状态,最后决定是 symlink 还是 fallback 到复制。
-
composer install不读repositories,只读composer.lock -
composer update才执行完整解析,才可能创建软链接 - 手动
ln -s或 Windowsmklink完全无效:Composer 后续命令(如dump-autoload)会直接覆盖或删除它
path 仓库启用 symlink 的三个硬性条件
缺一不可。Composer 不报错,只默默退化成拷贝模式,你看到的 Symlinking 日志可能是误导。
-
url必须是相对路径(如"../my-package")或绝对路径(如"/Users/me/my-package"),不能带file://,不能用~/;Windows 下必须用正斜杠/或双反斜杠\ -
name字段(如"acme/utils")必须和主项目require中的字符串逐字节一致:大小写、斜杠方向、连字符都不能差 -
options.symlink必须显式写在主项目的repositories条目里,像这样:{"type": "path", "url": "../my-package", "options": {"symlink": true}};放在本地包自己的composer.json或全局config里都无效
版本号写 * 或 dev-main 才能命中 path 源
path 类型仓库不提供版本元数据,Composer 只认 dev- 开头的分支名,或通配写法。写 ^1.0、~2.0 这类语义化约束,Composer 直接忽略该源,转头去 Packagist 查。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 最稳写法是
"acme/utils": "dev-main",前提是本地包 Git 有main分支(.git/refs/heads/main存在) -
"*"等价于"*@dev",但要求本地包至少有一个 commit,否则 Composer 拒绝加载(不报 Git 错误,只报Could not find package) - 本地包没初始化 Git 时,Composer 默认 fallback 到
dev-main,此时写"dev-main"仍有效;写"dev-master"就失败
如何确认软链接是否真正生效
别信日志,看文件系统。Linux/macOS 上运行:
ls -la vendor/acme/utils
如果输出末尾含 -> /absolute/path/to/my-package,说明是真实符号链接;如果只是普通目录,说明前面三个条件中至少有一处没满足。
Windows 用户可用 dir vendorcmeutils 查看,若显示 <symlinkd></symlinkd> 即为成功。注意:PowerShell 的 Get-ChildItem 默认不显示链接目标,得加 -Force 参数。
容易被忽略的是 Git 状态:本地包根目录下必须有合法 composer.json,且该目录必须是 Git 工作区(哪怕没 remote)。否则 Composer 会拒绝 symlink,且不提示原因。










