
禁用默认 Packagist 源后仍访问 packagist.org,因 Composer 2.0+ 将其设为元数据兜底;必须在 repositories 数组中显式声明 type: "packagist" 的替代源并同级配置 "packagist.org": false。
composer install 仍尝试访问 packagist.org?这是最常被忽略的细节:禁用默认源不等于移除 Packagist 的元数据索引逻辑。Composer 在 2.0+ 中引入了「pac

"packagist.org": false,只要没显式声明其他 packagist 类型仓库(比如私有镜像),composer install 仍可能在解析依赖时触发对 packagist.org 的 DNS 查询或 404 请求。
实操建议:
repositories 数组中显式添加一个类型为 packagist 的替代源(哪怕只是空配置)"packagist.org": false 是 repositories 的子项,而非顶层配置composer config --global repositories.packagist false 仅影响全局配置,项目级 composer.json 会覆盖它repositories 中如何正确定义禁用 + 替代 packagist 源?关键不是“删掉”,而是“替换并关闭”。错误写法是只写 {"packagist.org": false};正确结构必须包含一个 type: "packagist" 的条目,并把 url 指向你的私有镜像(如阿里云、腾讯云或自建 Satis)。
示例(composer.json 中):
{
"repositories": [
{
"type": "packagist",
"url": "https://mirrors.aliyun.com/composer/"
},
{
"packagist.org": false
}
]
}
注意点:
repositories 数组内,顺序无关type: "packagist" 条目会接管所有未限定仓库的包发现逻辑/packages/list.json 和 /p/[vendor]/[package]/[version].json 接口composer require 还会报 Could not find package xxx at any version?这不是网络问题,而是 Composer 在禁用默认源后,无法自动推导出「哪些包属于哪个仓库」。尤其当你要安装的包从未在你指定的私有镜像中同步过,或者镜像本身未开启 full-sync 模式,就会失败。
排查路径:
composer show -p | grep xxx 看包是否在当前可用仓库列表中composer config repositories.packagist.org https://packagist.org,成功后再手动同步到私有源type: "composer" 和 type: "packagist" 仓库处理同一类包,会导致优先级冲突config.repos.packagist 全局设置和项目级 composer.json 的优先级关系项目级 composer.json 中的 repositories 始终覆盖全局配置。但容易被忽略的是:composer config --global repositories.packagist false 实际写入的是 ~/.composer/config.json,而该文件中的 repositories 是一个对象,不是数组 —— 它只能控制是否启用默认源,不能定义新仓库。
所以真正生效的禁用动作,必须落在项目级配置里。常见误操作:
composer.json → 无效"packagist.org": false,但漏了 type: "packagist" 替代项 → 降级回默认行为composer config repositories.foo ... 命令追加仓库,结果生成的是 object 而非 array,导致解析失败复杂点在于:Composer 不校验 repositories 结构合法性,错误配置只会静默失效或部分生效。