答案是包不存在主因是 Composer 未访问私有源:repositories 顺序错误、packagist.org 未禁用(需{"packagist.org": false}独立置末)、VCS type 写错(须为"vcs"而非"git")或 URL 不合法。

包不存在不是网络问题,而是 Composer 根本没去你配的源里找——repositories 顺序错、packagist.org 没关、或 type 写成 git 而非 vcs,都会导致静默跳过私有源。
为什么 composer search 能搜到,require 却报 “Package not found”
composer search 只查 packagist.org 全局索引,不校验 PHP 版本、扩展、稳定性,也不读你本地的 repositories 配置;而 require 是真安装,会严格按 repositories 数组顺序 + minimum-stability + 实际元数据匹配。常见现象:
- 包只有
dev-main版本,但项目设了"minimum-stability": "stable"→ 直接跳过,报 “not found”,不是 “版本不匹配” -
composer search myorg/utils成功,不代表你能装:可能只是 Packagist 上有个同名空包,你的私有源压根没被访问 - 运行
composer config repositories,输出里如果还包含https://repo.packagist.org,说明packagist.org没禁用,私有源再靠前也白搭
repositories 配置生效的三个硬性条件
Composer 查包是「从上到下,命中即停」,但这个逻辑只在 packagist.org 被显式关闭后才启用。否则它永远先查官方源兜底。必须同时满足:
-
{"packagist.org": false}必须是repositories数组里的一个**独立对象**,不能嵌套进其他仓库配置里 - 它必须放在私有源之后、数组末尾(不是开头),例如:
"repositories": [ {"type":"composer","url":"https://pkg.myorg.com/"}, {"packagist.org": false} ] -
type必须写"vcs"(不是"git"、"github"或漏掉),URL 必须是可git clone的地址,且结尾**不能带.git后缀以外的路径**(如https://gitlab.example.com/myorg/utils.git✅,https://gitlab.example.com/myorg/utils.git#main❌)
依赖目录重建:不是删 vendor 就完事
只删 vendor 目录,composer install 仍会复用 composer.lock 和缓存里的旧 zip 包。要真正重拉,必须切断三处来源:
- 删掉项目根目录的
composer.lock(否则install是“复原”,不是“重算”) - 运行
composer clear-cache清掉~/.composer/cache/files/下所有 zip - 执行
composer install --no-cache—— 此时 Composer 会按composer.json重新解析依赖树,并全部走网络下载 - 若仍卡在
Downloading (0%),大概率是镜像没生效,检查composer config -g repo.packagist输出是否为带type和尾斜杠的 HTTPS URL(如https://mirrors.aliyun.com/composer/)
私有包路径改了,autoload 还是报错?
改 config.vendor-dir 后,vendor/autoload.php 变成 libs/autoload.php,但代码里所有 require 'vendor/autoload.php' 还是原样——结果就是 Class not found。关键点:
-
COMPOSER_VENDOR_DIR环境变量在 Composer 2.x 中已彻底失效,设了也完全不生效 - 唯一可靠方式是在
composer.json的config字段下配vendor-dir,且值必须是相对路径(如"libs"),不能以/开头 - 改完后,所有
require语句、CI 脚本、IDE 的 Include Paths、甚至artisan内部 require 都得同步更新











