必须全局禁用隐式兜底并项目级声明"packagist": false,否则Composer 2.0+仍会访问packagist.org;设repo.packagist为false无效,应--unset或置null,且需配合clear-cache及正确repositories配置。

禁用默认 Packagist 源不是“删掉配置”或“设为 false 就完事”,必须同时满足两个条件:全局关掉隐式兜底行为 + 项目级显式声明仓库策略,否则 composer install 仍会偷偷连 packagist.org、拉错包、甚至超时失败。
为什么 composer config -g repo.packagist false 有时没用
这条命令在 Composer 2.0+ 中已不推荐——它把 repo.packagist 设为布尔 false,而 Composer 实际只接受 null、对象或完全删除该字段。设成 false 后,Composer 会静默忽略并 fallback 到内置 https://packagist.org。
- 验证方式:
composer config -g repo.packagist输出false≠ 生效;真正生效是执行composer config -g --unset repo.packagist或composer config -g repo.packagist null - 注意:
--unset删除字段,null是合法值,两者都可让 Composer 放弃兜底逻辑 - 执行后必须跟
composer clear-cache,否则旧缓存仍可能触发外网请求
composer.json 里必须写 "packagist": false(不是 packagist.org)
全局配置只控制默认源是否启用,但项目级 composer.json 的 "packagist": false 才是最终开关——它告诉 Composer:“别管全局配了啥,这个项目坚决不用任何 packagist 行为”。
- 必须放在
composer.json顶层,不是repositories数组里 - 大小写敏感,写成
"Packagist": false或"packagist.org": false都无效 - 错误示例:
"repositories": [{"packagist.org": false}]—— 这个条目会被忽略,packagist.org依然隐式加载
禁用后 Could not find package 怎么办
这不是网络问题,是 Composer 不再自动推导包归属。它不会扫描你所有 repositories 去找包,而是严格按仓库声明的协议和索引接口匹配。
- 私有 Satis 服务必须支持
/packages/list.json和/p/{vendor}/{package}/{version}.json接口,否则require会直接失败 - 如果某个包只在
packagist.org上有(比如小众工具),又不想开公网,只能临时加回:composer require foo/bar --repository=https://packagist.org - 检查镜像是否同步完整:访问
https://your-mirror.example.com/packages/list.json,确认目标包名出现在返回的 JSON 数组里
验证是否真禁用了 packagist.org
不能只看配置文件有没有 "packagist.org": false,要观察实际网络行为。
- 运行:
composer require monolog/monolog --no-install --verbose - 看输出里元数据请求的 URL:正确应是你的私有地址(如
https://packages.internal/p/monolog/monolog/2.x-dev.json),绝不能出现repo.packagist.org或packagist.org - 再跑一次
composer config -g -l | grep repositories,输出中不应含repo.packagist字样,且只列出你手动加的可信源
最容易被忽略的是:禁用默认源后,repositories 数组里的每个条目都必须带 "type",且类型要和实际服务匹配——把 Satis 当 vcs 配,或把 GitLab 当 composer 配,都会导致静默失败,报错却只说“找不到包”。


















