Composer无全局黑名单,需通过composer.json的conflict字段(解析阶段拦截版本)、repositories.exclude(源级过滤)或roave/security-advisories(CVE级黑名单)实现排除,三者作用环节与目标各不相同。

如何查看当前 Composer 的黑名单包列表
Composer 本身没有全局“黑名单”概念,所谓黑名单实际是通过 composer.json 中的 replace 或 conflict 字段,或通过 repositories 配置伪造空包来实现屏蔽。最直接、可验证的方式是检查项目根目录下的 composer.json:
-
"replace":声明本项目“替代”哪些包(如"monolog/monolog": "*"),Composer 会跳过安装被 replace 的包,即使其他依赖要求它 -
"conflict":明确禁止某些包版本共存(如"ext-xdebug": "),安装时若冲突会报错 <code>Your requirements could not be resolved -
"repositories"中 typepackage且 name 匹配某包但无 dist/source,也可能造成“假装存在却无法安装”的屏蔽效果
运行 composer show --locked 不会显示被 replace 或 conflict 排除的包;真正被成功屏蔽的包,在 composer install 日志里通常表现为 “skipping package X because it is replaced” 或 “conflict with …”。
为什么 composer prohibit 不是标准命令
很多人搜 composer prohibit 是想找官方黑名单命令,但它并不存在。Composer 从未提供运行时动态拉黑包的 CLI 功能。所有“屏蔽”行为都必须提前写死在 composer.json 或自定义仓库配置中。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 第三方插件如
hirak/prestissimo或roave/security-advisories也只是靠conflict实现——后者本质是一份全量漏洞包版本冲突表,通过composer require roave/security-advisories:dev-master注入到你的composer.json - 试图用
config platform模拟扩展缺失来触发 conflict(如"platform": {"ext-gd": "0"})属于 hack,仅对依赖扩展的包生效,不通用 - 修改
vendor/composer/installed.json手动删条目?无效。下次install或update会立即还原
排查“疑似被黑”但没报错的包
常见现象:某个包明明在 require 里,composer install 却没装进 vendor/,也没有报错。这时重点查三处:
- 执行
composer why-not vendor/package-name—— 它会告诉你该包为何未被安装,例如 “because it is replaced by your project” 或 “because of conflict with …” - 检查是否有父级依赖用了
replace:比如你 requirefoo/bar,但bar/baz在其composer.json里写了"replace": {"foo/bar": "*"},那foo/bar就不会落地 - 运行
composer update --dry-run -v,加-v后会打印 resolver 决策过程,搜索 “replacing” 或 “conflict” 关键字,能定位到哪一行规则起了作用
替换/冲突规则写错的典型后果
写 replace 或 conflict 时一个字符偏差就可能导致意料外行为:
-
"replace": {"monolog/monolog": "*"}→ 正确屏蔽整个 monolog 包 -
"replace": {"monolog/monolog": "1.*"}→ 只屏蔽 1.x,2.x 仍可能被装,容易漏 -
"conflict": {"php": "8.3.0"}→ 写成具体小版本,而实际环境是8.3.1,冲突不触发 - 大小写敏感:
"monolog/monolog"≠"Monolog/Monolog",后者根本不会匹配
最隐蔽的问题是:某些包(如 Laravel 的 laravel/framework)自身大量使用 replace 声明替代组件,如果你的项目又额外 replace 同一包,Composer 解析器可能因规则叠加产生非预期跳过,此时必须看 --dry-run -v 输出才能确认优先级。

















