Composer本地包开发唯一可靠方式是声明type: "path"仓库:需删composer.lock和vendor后重装,确保软链接生效且autoload配置正确,否则将导致类加载失败或代码修改不生效。

必须用 type: "path",其他方式都会失效
Composer 本地包开发只有一条可靠路径:在项目 composer.json 中声明 type: "path" 仓库。任何绕过它的做法——比如手动复制进 vendor/、用 composer require vendor/pkg:@dev 指向 Git 仓库、或全局安装——都会导致类加载失败、改代码不生效、测试跑不通。
原因很直接:type: "path" 是唯一让 Composer 创建符号链接(Linux/macOS)或目录映射(Windows)的机制,它跳过版本解析和远程下载,把你的本地目录当作“已安装包”对待。其他方式全走标准依赖解析流程,根本不会建立实时映射。
-
url值必须是相对路径(如"../mylib"),不能以/开头,否则 Windows 下会解析成绝对路径并静默失败 -
require中的包名(如"myvendor/mylib")必须与本地包composer.json中的"name"字段**逐字符一致**(含大小写、连字符、斜杠) - 本地包的
composer.json中建议显式设"minimum-stability": "dev"和"prefer-stable": false,否则稳定性约束可能让它被跳过
composer.lock 存在时,repositories 配置完全被忽略
这是最常踩的坑:你刚加好 repositories,执行 composer update 或 composer install,结果包还是从 Packagist 下载,本地路径没生效。
根本原因是:Composer 只在首次安装或 composer.lock 缺失时读取 repositories;一旦锁文件存在,它就严格按锁文件还原,完全无视新配置。
- 必须先删掉
composer.lock - 必须删掉整个
vendor/目录(残留旧包会导致 autoload 仍指向原位置) - 再运行
composer install(不是update),它才会重新解析composer.json并生成新锁文件
如果只想重装单个包,可执行 composer remove myvendor/mylib && composer require myvendor/mylib,但前提是 repositories 已存在且结构正确——否则 remove 后 require 依然找不到。
验证是否真走 path 流程:别信 vendor 目录,要看链接和类加载
执行完 composer install 后,不能只看 vendor/myvendor/mylib 是否存在,得确认它是链接还是真实目录,以及类是否能被加载。
- Linux/macOS 下运行
readlink vendor/myvendor/mylib,输出应为你的本地路径(如../../mylib);若输出为空,说明仍是普通目录,没走 path 流程 - Windows 下运行
dir vendormyvendormylib,观察是否显示“目录交接”或目标路径(而非“子目录”) - 执行
php -r "echo class_exists('MyPackage\Calculator') ? 'ok' : 'fail';",输出ok才说明生产 autoload 生效 - 若测试类报
Class not found,大概率是本地包composer.json的autoload或autoload-dev配置错位(比如 PSR-4 映射末尾漏了反斜杠"MyPackage\Tests\": "tests/")
改了本地代码却不生效?检查软链接是否还在
type: "path" 创建的链接不会自动更新。你改了本地库的代码,主项目却没变化,常见原因只有一个:上次 composer install 没真正走 path 流程,vendor/myvendor/mylib 是个残留的真实目录,不是链接。
- 删掉
vendor/myvendor/mylib,再跑一次composer install(确保composer.lock已删) - 确认
autoload-dev修改后,必须手动运行composer dump-autoload --dev,否则vendor/composer/autoload_dev.php不更新 - 无命名空间的辅助文件(如
tests/bootstrap.php)不能塞进 PSR-4,得用autoload-dev.files单独引入
复杂点在于:这个机制依赖操作系统级的符号链接或目录映射,而 Windows 对交接的支持不如 Linux/macOS 稳定;一旦链接断开,Composer 不会报错,只会静默 fallback 到 copy 模式——这时你看到的 vendor 内容是快照,不是实时反射。


















