答案是“Package not found”主因是源未生效、顺序错误、packagist.org未禁用或元数据过期;composer search仅查Packagist全局索引,require则严格按repositories顺序+minimum-stability+实际元数据匹配执行。

“Package not found”不是包真没了,而是 Composer 根本没去你期望的地方找——源没生效、顺序错、packagist.org 没关、元数据过期,四者占其三。
为什么 composer search 能搜到,composer require 却报错
因为 composer search 只查 packagist.org 全局索引,不校验 PHP 版本、扩展、稳定性或你本地的 repositories 配置;而 composer require 是真安装,会严格按 repositories 顺序 + minimum-stability + 实际元数据匹配执行。
- 你搜到的可能是同名空包(比如
myorg/utils在 Packagist 上只是个占位页),你的私有源压根没被访问 -
composer search成功 ≠ 你能装,它连https://mirrors.aliyun.com/composer/都不碰 - 运行
composer config repositories,如果输出里还包含https://repo.packagist.org,说明packagist.org没禁用,私有源再靠前也白搭
repositories 配置生效的三个硬条件
Composer 查包是「从上到下,命中即停」,但这个逻辑只在 packagist.org 被显式关闭后才启用。否则它永远先查官方源兜底。
-
{"packagist.org": false}必须是repositories数组里的一个独立对象,不能嵌套进其他仓库配置里 - 它必须放在私有源之后、数组末尾(不是开头)
- Composer ≥ 2.2 的正确键名是
repos.packagist(复数),写成repo.packagist会静默忽略
镜像源同步延迟和本地元数据缓存问题
国内镜像(阿里云、腾讯云等)对 packagist.org 的同步有 5–30 分钟延迟,高峰期可能更久。新发布的包或刚更新的版本,在镜像里可能还没出现。
- 打开浏览器访问
https://mirrors.aliyun.com/composer/p/vendor/package-name.json(替换为实际包名),如果返回 404 或内容里没有目标版本,就是镜像没同步 -
composer clear-cache不会强制重新下载远程的packages.json——Composer 默认复用本地缓存中未过期(15 分钟内)的元数据快照 - 真正要删的是缓存目录下的具体镜像子路径,比如:
rm -rf ~/.composer/cache/repo/https---mirrors-aliyun-com-composer
项目级 repositories 静默覆盖全局镜像
项目根目录若有 composer.json 且含 "repositories" 字段(哪怕只是空数组 []),就会完全屏蔽全局镜像;此时 composer config repo.packagist(不加 -g)才反映真实配置。
- 检查项目
composer.json是否意外写了"repositories": []或残留了已停用的旧镜像 URL(如"https://packagist.phpcomposer.com") - 临时验证是否镜像问题:运行
composer config --global repo.packagist composer https://packagist.org,再试composer require vendor/package -vvv - 若成功,说明问题出在镜像;失败则可能是包名拼错、
minimum-stability约束过严、或私有源配置干扰
最常被忽略的点:你以为改了配置就生效了,但 composer config -g repos.packagist 输出为空,或者日志里还在打印 Downloading https://packagist.org/——那说明配置根本没落进 Composer 的运行上下文里,所有后续排查都建立在错误前提上。


















