必须显式指定版本如dev-main或@dev,因本地包无tagged版本且默认stable策略不匹配;需在主项目composer.json中配置path型repositories,并确保本地包autoload映射正确且执行dump-autoload。

require 命令必须带明确开发版本,不能省略
直接 composer require vendor/name 会失败,因为 Composer 默认按 stable 稳定性策略解析,而本地包通常没有 tagged 版本。它不会“自动猜”你想要 dev-main 或 @dev。
正确写法只有两种主流情况:
-
composer require mycompany/utils:dev-main—— 要求本地包目录下有 Git 仓库,且当前分支是main(或master),同时其composer.json中"version"字段可选但推荐设为"dev-main" -
composer require mycompany/utils:@dev—— 要求主项目已设"minimum-stability": "dev",否则仍会因稳定性检查失败而中止
别写 :*、:latest 或空版本,这些在 path 仓库中不被识别,Composer 会直接报 Could not find package。
repositories 配置必须写在主项目 composer.json 根级
路径仓库不是靠环境变量、全局配置或命令行参数生效的,它只认主项目根目录下 composer.json 最外层的 repositories 数组。
常见错误配置:
- 把
repositories塞进config或require里 —— 静默忽略 -
"url": "../my-pkg/"(末尾带/)—— 解析失败,跳过该仓库 -
"url": "/home/user/my-pkg"(绝对路径)—— 多数场景静默失效,尤其 CI/Docker -
"type": "package"—— 不支持 autoload、scripts、autoload-dev 等完整功能,应避免
正确示例(写在主项目 composer.json 顶层):
"repositories": [
{
"type": "path",
"url": "../my-utils"
}
]
其中 ../my-utils 必须是一个**含合法 composer.json 的目录**,不是文件,也不可包含中文或空格(Windows 下尤其敏感)。
symlink 是否生效,得看本地包自己的 composer.json
很多人以为在主项目配 "options": {"symlink": true} 就能强制链接,其实没用 —— 这个配置必须出现在**本地包自己目录下的 composer.json 里**。
不加这句,Composer 在 Linux/macOS 可能侥幸成功链接,但在 Windows 或 Docker 中几乎必然 fallback 到复制(copy)模式:你改了本地代码,vendor/ 里还是旧副本,调试全白忙。
验证是否真链接成功:
- Linux/macOS:
ls -la vendor/mycompany/utils,输出含-> ../my-utils才对 - Windows:
dir vendormycompanyutils,看到JUNCTION或SYMLINKD字样才算
Windows 用户还必须以管理员身份运行终端,否则 symlink 创建失败且无任何提示。
autoload 映射更新要手动触发,且路径必须严格匹配
即使 vendor/ 里包已存在、链接也正确,Class not found 仍大概率是 autoload 没加载到真实路径。
关键点:
- 本地包的
composer.json必须正确定义"psr-4",例如:"MyCompany\Utils\": "src/"—— 注意双反斜杠和末尾反斜杠 - 如果测试类在
tests/目录,且用了autoload-dev,映射末尾必须带反斜杠:"MyCompany\Tests\": "tests/",少一个就断掉 - 改完 autoload 配置后,必须运行
composer dump-autoload(开发阶段不用加-o),否则新映射不会写入vendor/composer/autoload_static.php - 别在
require 'vendor/autoload.php'之前实例化类,也别用require_once手动引入源文件 —— 这绕过了 Composer 自动加载机制
最隐蔽的问题是 IDE 路径与磁盘真实路径不一致,Xdebug 断点打不进、get_declared_classes() 查不到类,往往卡在这一步。











