根本原因是composer未在主项目composer.json的repositories中声明path源,它只按该数组查找包源,require仅声明需求而不指定位置;必须配置合法path仓库、本地包含匹配name的composer.json、版本用dev-main等分支名,并启用symlink选项才能生效。

为什么composer require vendor/name:dev-main总报“Could not find package”
根本原因不是网络或权限,而是 Composer 根本没“看见”你的本地目录。它只在主项目 composer.json 的 repositories 数组里找源,require 字段只声明“我要谁”,不负责“去哪找”。
-
repositories必须写在主项目(你正在开发的那个项目的)composer.json里,不能写在本地包自己的composer.json中 -
url必须是相对路径(如"../my-package"),绝对路径在 Windows 上极易静默失败(盘符、反斜杠、空格都会中断) - 本地包目录下必须有合法的
composer.json,且其中name字段(如"acme/utils")要和require里写的完全一致(大小写敏感、分隔符只能用短横线-) - 版本约束必须用
dev-main、dev-develop这类分支名,不能写1.0.0——path 源下 Composer 忽略version字段,只认当前 Git HEAD 所在分支
改了本地包代码,为什么主项目里还是旧行为
默认行为是复制(copy),不是链接(symlink)。你改了 ../my-package/src/Helper.php,vendor/acme/utils/Helper.php 还是旧文件。
- 必须显式启用符号链接:在**本地包自己的**
composer.json里加"options": {"symlink": true}(不是主项目配,这点最容易错) - 执行
composer update acme/utils(不是dump-autoload),才会重建 symlink - 验证是否成功:
ls -la vendor/acme/utils应显示箭头指向源目录;Windows 用户用dir vendor\acme\utils看是否为“快捷方式”或JUNCTION类型 - Windows 需开启开发者模式或以管理员权限运行命令行,否则 symlink 创建会失败且无提示
composer install 和 composer update vendor/name 到底该用哪个
composer install 只重建缺失的链接,不会刷新已有链接的目标路径。它依赖 composer.lock 记录的当前解析结果,而这个结果在首次 require 或 update 时就已固化。
- 改完本地包代码后,
composer install什么也不做 - 必须运行
composer update acme/utils才会重新解析 path、重建 symlink -
composer update不带参数会全量重算,慢且易引入意外变更;指定包名更快、更安全 - 首次引入时,
composer require acme/utils:dev-main也会触发 symlink 创建
生产部署前最常被忽略的一件事
path 仓库配置无法在生产环境直接复用——服务器上不存在 ../my-package 这个路径,Composer 会直接报错,且不会自动 fallback 到 Packagist。
- CI/CD 流程中必须移除
repositories中的 path 条目,或用构建脚本动态替换 - 团队协作时不要把硬编码的
url提交到 git,可考虑用环境变量 + 自定义脚本注入,或使用studio这类专用工具临时管理 - 本地包若未初始化 Git(
git init后至少一个 commit),Composer 会拒绝加载,且不提示具体原因











