必须用 path 类型仓库,因 Composer 默认只从远程仓库拉包,本地代码需在 repositories 中声明且配置正确才能被识别和加载。

必须用 path 类型仓库,其他方式基本都会导致类加载失败或改了代码不生效。
为什么 composer require vendor/name 不能直接装本地代码
Composer 默认只从 Packagist 或配置的远程仓库拉包,require 后面写的版本号(比如 "^1.2")会触发远程解析,根本不会看你电脑上有没有同名目录。就算你把源码 clone 到 ./packages/my-package,只要没在 repositories 里声明,它就当不存在。
常见错误现象:
- 执行
composer require vendor/name报Could not find package vendor/name - 手动把代码复制进
vendor/,但class_exists('VendorClass')返回false - 改了本地包里的 PHP 文件,主项目运行结果完全没变化
怎么配 path 仓库让 Composer 找到本地包
在主项目的 composer.json 顶部加 repositories 块,url 必须是相对于该文件的路径,且目标目录下必须有合法的 composer.json(含 name 和 version)。
示例配置:
{
"repositories": [
{
"type": "path",
"url": "../my-local-package"
}
],
"require": {
"vendor/my-local-package": "dev-main"
},
"minimum-stability": "dev",
"prefer-stable": true
}
关键点:
-
url不能用~/、/full/path或../跨出项目根目录(Composer 2.5+ 会直接拒绝) -
require中的版本号必须匹配本地包composer.json里的version字段,比如写"dev-main",就不能指望"dev-master"生效 - 必须设
"minimum-stability": "dev",否则dev-main这类开发版会被过滤掉 - 改完后别直接
composer install——先删掉composer.lock,否则旧锁文件会跳过新仓库
composer update vendor/name 之后还是没链接成功?检查这三处
执行完 composer update vendor/my-local-package,vendor/vendor/my-local-package 应该变成符号链接(Linux/macOS)或目录映射(Windows)。如果没变,大概率是下面某个环节断了:
- 本地包
composer.json的name字段和主项目require里的名字不一致(大小写、连字符、斜杠位置错一个都不行) - 本地包目录下没有
autoload配置,或者 PSR-4 映射末尾漏了反斜杠,比如写成"MyPackage\": "src"而不是"MyPackage\": "src/" - 主项目没运行
composer dump-autoload,autoload 文件没更新,类自然找不到
验证是否真生效:
- Linux/macOS 下执行
readlink vendor/vendor/my-local-package,输出应为相对路径 - 运行
php -r "echo class_exists('MyPackage\Helper') ? 'ok' : 'fail';",输出ok才算 autoload 通了
别碰 composer link,除非你清楚它只对已安装包有效
composer link 不是通用方案,它只对「已经通过 composer require 安装过的包」起作用,本质是在 vendor/ 下建软链接,但不改 composer.lock,也不同步 autoload 规则。一旦后续执行 composer update,链接大概率被覆盖回远程包。
如果你只是想快速调试,又没在 repositories 里提前配好 path 仓库,那它可能“看起来快”,但实际埋了坑:
- 本地包还没 install 过,
composer link直接报错 - 链接建好了,但
composer dump-autoload没自动触发,类还是加载不到 - 团队协作时,别人
composer install根本拉不到你的本地路径,CI 也会挂
真正需要稳定复现、多人共享、CI 可跑的本地调试流程,只有 path 仓库这一条路走到底。路径对齐、name 一致、autoload 写对、lock 文件重生成——少一个环节,vendor/ 里就只是个死目录。


















