答案是:必须用path仓库类型,因其强制符号链接或目录映射、跳过版本校验、确保autoload实时生效;其他方式(如手动复制、vcs require、global install)均导致autoload失败或修改不生效。

本地包必须用 path 仓库类型,其他方式全失效
Composer 对本地包的唯一可靠支持方式是 path 类型仓库。它强制创建符号链接(Linux/macOS)或目录映射(Windows),跳过版本校验、不走 Git 克隆、不依赖远程解析——改完代码立刻生效,autoload 实时加载。任何试图绕过它的做法都会失败:
-
composer require vendor/package:@dev+ vcs 仓库:仍会 clone 一次,改代码必须 commit/push 才能被主项目感知 - 手动拷贝到
vendor/:autoload 不注册、composer dump-autoload无效、Windows 下静默 fallback 成复制,彻底断 autoload - 全局安装:
composer global require完全脱离当前项目上下文,DI 容器、配置、测试环境全错位
三处 name 和路径必须严格对齐,差一个字符就报错
“Could not find package” 这类错误,90% 是因为三个地方没对齐。不是大小写问题,是字符串字面量完全一致:
- 主项目
composer.json的repositories中url值:必须是相对于该文件的路径,比如"../my-local-package" - 主项目
require中的包名:必须和本地包composer.json里的"name"完全一致,且推荐用"@dev"而非"*"或"dev-main" - 本地包根目录的
composer.json中"name"字段:如"my-vendor/my-local-package",连字符、斜杠、大小写一个都不能错
autoload 和 autoload-dev 配置写错,类永远加载不到
类找不到不是 PHPUnit 的问题,是自动加载链路断在了第一步。关键细节:
-
autoload.ps4映射末尾必须带反斜杠:"MyLocalPackage\": "src/",少这个就不匹配 -
autoload-dev.ps4同理,且层级要和实际文件结构一致:如果tests/MyLocalPackage/Http/ClientTest.php声明namespace MyLocalPackageHttp,那配置就得是"MyLocalPackage\Http\": "tests/MyLocalPackage/Http/"或更通用的"MyLocalPackage\Tests\": "tests/" - 无命名空间的辅助文件(如
tests/bootstrap.php)不能塞进 PSR-4,得用autoload-dev.files单独引入 - 改完 autoload 配置后,必须手动运行
composer dump-autoload --dev,否则vendor/composer/autoload_dev.php不更新
验证是否真生效,别只看 vendor 目录
执行 composer update my-vendor/my-local-package 后,不能只检查 vendor/ 里有没有目录。必须确认底层链路通了:
- Linux/macOS 下运行
readlink vendor/my-vendor/my-local-package,输出应为指向你本地包路径的符号链接 - Windows 下运行
dir vendormy-vendormy-local-package,确认是目录映射而非复制内容 - 执行
php -r "echo class_exists('MyLocalPackage\Calculator') ? 'ok' : 'fail';",输出ok才说明生产 autoload 生效 - 再跑
php -r "echo class_exists('MyLocalPackage\Tests\ClientTest') ? 'ok' : 'fail';",验证 dev autoload 是否就绪
最容易被忽略的是 autoload-dev 的反斜杠和 dump-autoload --dev 这一步——它不随 install 或 update 自动触发,必须手动执行。











