composer install 不下载新包是因为它只依据 composer.lock 文件还原依赖,忽略 composer.json 中手动新增或修改的 require;必须用 composer require 或 composer update 同步 lock 文件。

为什么 composer install 不会装你刚加进 composer.json 的本地包
因为 composer install 完全不读 composer.json 里的新增或修改项,它只按 composer.lock 还原已知状态。你手动往 composer.json 的 require 里加了一行 "myorg/local-lib": "dev-main",但没运行任何命令同步到 lock 文件,composer install 就当它不存在。
常见错误现象:
- 本地改完
composer.json,执行composer install,vendor里压根没这个包 - CI 构建失败,报
Class not found,但你在自己机器上composer require是成功的
正确做法只有两个:
- 用
composer require myorg/local-lib:dev-main—— 它自动写入composer.json、更新composer.lock、下载并软链(或复制)包 - 手动改完
composer.json后,必须立刻跑composer update myorg/local-lib,不能只install
怎么让 Composer 从项目外目录加载本地包
关键不是“安装到哪”,而是“从哪找”。Composer 本身不支持全局路径依赖,但它允许你声明一个本地文件系统路径作为临时仓库——这就是 repositories + type: "path" 的作用。
操作步骤:
- 确保你的本地包(比如
../my-shared-lib)有合法的composer.json,且含"name": "myorg/local-lib" - 在主项目的
composer.json里加一段:
{
"repositories": [
{
"type": "path",
"url": "../my-shared-lib"
}
],
"require": {
"myorg/local-lib": "dev-main"
}
}
注意:"dev-main" 必须和本地包的 composer.json 中 "version" 字段或分支名一致;若本地是 main 分支,就写 "dev-main",不是 "*" 或 "@dev"(后者可能触发 Packagist 回退)。
执行 composer require myorg/local-lib:dev-main 后,默认会在 vendor/myorg/local-lib 创建符号链接,指向 ../my-shared-lib。改那边的代码,这边立刻生效。
调试时怎么避免 symlink 导致 IDE 跳转失效或断点不命中
IDE(如 PHPStorm)对 symlink 的支持取决于配置和文件系统权限。常见问题:点击类名跳不到源码、断点灰色、var_dump 显示路径是 vendor/... 而非真实路径。
解决办法分两层:
- 确认 symlink 已创建:
ls -l vendor/myorg/local-lib应显示指向外部目录的链接;若显示普通文件夹,说明type: "path"没生效,检查repositories.url路径是否拼错、是否用了相对路径但当前工作目录不对 - PHPStorm 中打开
Settings > Languages & Frameworks > PHP > Composer,勾选Follow symlinks;再右键vendor/myorg/local-lib→Mark as Sources,强制识别为源码根目录 - 如果仍不行,临时改用
"options": {"symlink": false}配置,让 Composer 复制而非链接(适合 Windows 或 NFS 共享卷):
{
"repositories": [
{
"type": "path",
"url": "../my-shared-lib",
"options": {
"symlink": false
}
}
]
}
上线前必须清理掉 path 仓库配置
repositories 里的 type: "path" 是开发期专用机制,生产环境无法访问本地文件系统路径。如果忘记删,部署时 composer install 会直接报错:Could not find package myorg/local-lib at any version。
安全做法:
- 永远不要把
repositories提交到主干分支;用 Git 的git update-index --skip-worktree composer.json锁定该字段,或拆出composer.local.json并通过COMPOSER环境变量切换(需脚本支持) - CI/CD 流水线中,部署前用
composer remove myorg/local-lib && composer require myorg/local-lib:^1.2切回 Packagist 正式版本 - 上线前人工检查:运行
composer show myorg/local-lib,输出中的source行不应包含../或绝对路径,而应是https://github.com/...类型
最容易被忽略的一点:团队成员之间不共享 composer.lock 里的 packages 条目来源信息。你本地装的是 symlink,别人 install 时若没配 repositories,就会去 Packagist 找 dev-main——这根本不存在。所以 composer.lock 里一旦出现 path 类型包,就必须确保所有协作者都启用相同 repositories 配置。











