最常见原因是Composer缓存了旧的symlink或dist包,尤其使用path仓库时默认优先走dist;需确认repositories配置、删除vendor目录后重装,并检查composer.lock中source字段是否为path类型。

为什么 composer install 后本地包代码没更新?
最常见原因是 Composer 缓存了旧的 symlink 或 dist 包,尤其在你用 path 仓库方式引入本地包(如 "my/package": "dev-main" + "repositories" 配置)时。Composer 默认优先走 dist(zip 包),哪怕你改了本地源码,只要没触发重装,它就继续用缓存的副本。
实操建议:
- 先确认是否真在用
path类型仓库:检查composer.json中repositories是否含"type": "path",且对应包的版本约束是否匹配本地分支(比如本地是main,但require写的是"dev-develop") - 删掉
vendor/my/package目录再运行composer install—— 不要只靠composer update my/package,它可能跳过 symlink 重建 - 加
-v参数看详细日志:composer install -v,留意输出中是否有symlinking from /path/to/local/package,还是installing my/package (dev-main)后跟Downloading...
composer dump-autoload 真的能刷新类加载吗?
不能。这个命令只重新生成 vendor/autoload.php 和类映射(vendor/composer/autoload_classmap.php 等),前提是文件结构、命名空间、autoload 配置本身没变。如果你改了本地包里的类名、挪了文件位置、或没在包的 composer.json 里正确声明 autoload,dump-autoload 就只是“刷新了个寂寞”。
实操建议:
- 进到本地包目录,执行
composer dump-autoload(不是项目根目录!)—— 它会按包自己的autoload规则生成映射 - 检查本地包的
composer.json是否有"autoload": { "psr-4": { "My\Package\": "src/" } },且src/下文件命名和命名空间严格一致 - 如果用了
filesautoload,确认路径是相对于包根目录的,且 PHP 文件里没有语法错误(否则dump-autoload会静默失败)
如何确认当前加载的到底是本地代码还是 dist 包?
直接看 vendor/my/package 目录下的内容:如果里面是完整的 Git 仓库结构(含 .git 目录、composer.json、src/),说明是 symlink 到本地;如果只有 src/、tests/ 等文件,但没 .git,大概率是 Composer 下载并解压的 dist 包。
更可靠的方法是查 Composer 的锁文件和安装日志:
- 打开
composer.lock,搜索你的包名,在对应条目下看"source"字段是否存在,以及"type"是path还是package - 运行
composer show my/package,观察输出中的source行:如果是source: /absolute/path/to/your/local/package,说明链对了;如果是source: https://api.github.com/...,说明根本没走本地 path - 临时在本地包的某个类方法里加
echo "LOCAL HIT"; die;,然后触发调用——没输出?那根本没加载到它
Windows 下 symlink 失效的典型表现和绕过方式
Windows 默认不启用开发者模式时,mklink 权限受限,Composer 创建 symlink 会失败,转而 fallback 到 copy 模式(即把本地包整个复制进 vendor)。这就导致你改本地代码,vendor 里那份永远不变。
实操建议:
- 以管理员身份运行终端,执行
composer install—— 这能让 Composer 成功创建 symlink - 或者改用
"options": { "symlink": false }强制禁用 symlink,但必须配合"options": { "versions": { "dev-main": "dev-main" } }确保 Composer 不去下载 dist - 更稳妥的做法:在
repositories里把path改成绝对路径,并确保路径不含空格或中文(Windows 对路径解析更敏感)
真正卡住的时候,往往不是 Composer 配置写错了,而是你改了本地包代码,却忘了 git add && git commit —— Composer 的 path 仓库依赖 Git HEAD,没 commit 就等于没变更。











