conflict字段仅在当前项目依赖解析时生效,不构成全局黑名单;它写在根composer.json中,触发时直接报错退出,不安装也不写入lock文件。

conflict字段只在解析阶段生效,不是全局黑名单
Composer 没有真正的「全局黑名单」机制,conflict 是最接近的原生方案,但它只作用于当前项目的依赖解析环节——一旦 Composer 算出某个包版本会触发 conflict 规则,就直接报错退出,不下载、不安装、不写入 composer.lock。它不拦截已存在的包,也不影响其他项目。
- 必须写在项目根级
composer.json的"conflict"字段里,格式如:"conflict": {"monolog/monolog": ">=1.25.0"} - 版本约束支持
!=、^、~,但~2.0和^2.0行为不同,别靠经验猜 - 它不管间接依赖是否偷偷拉入——如果
package-a依赖monolog/monolog:^1.24,而你只conflict了1.25.0,那1.24.1仍会被装上 - 错误提示通常是:
Your requirements could not be resolved to an installable set of packages.后面跟着具体冲突项
roave/security-advisories 提供 CVE 级拦截,但不是实时的
roave/security-advisories 是目前唯一能接近「自动黑名单」效果的方案,但它本质是强制依赖一个由社区维护的已知漏洞列表包,靠 Composer 自身依赖求解器拒绝冲突版本——不是插件主动扫描,而是语义级冲突。
- 必须作为
--dev依赖安装:composer require --dev roave/security-advisories:dev-latest,global安装完全无效 - 它只比对已公开披露并被收录的 CVE,新漏洞从披露到收录存在延迟(截至 2026 年 7 月,平均延迟约 1–5 天)
- 不检查代码,不扫描 vendor 目录,只看
composer.lock中记录的版本是否匹配黑名单条目 - 若你项目中某个包版本已被收录为高危,但尚未更新
composer.lock,composer update会直接失败;已安装的旧版不会被自动卸载
repositories.exclude 只过滤源,不拦包
repositories.exclude 是源级过滤,不是包级黑名单。它只告诉 Composer:“别从这个源拉这些包”,但同名包仍可能从 Packagist 或其他仓库装进来。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 仅对当前
repositories数组中的某一条生效,多个源需分别配置 - 支持前缀通配符:
"acme/*"有效,"*tool"无效,不支持后缀或中间匹配 - 路径匹配基于包名全称,不是文件路径:
"exclude": ["monolog/monolog"]才能拦住它,"monolog"不行 - 不影响依赖解析逻辑,只跳过当前源的查找步骤;如果该包在其他源存在且满足约束,依然会被选中
真正可靠的“排除”永远靠 composer.lock + 固定版本
所有运行时参数或配置都可能被绕过或失效,唯一稳定可控的方式,是把目标包版本精确锁死,并提交 composer.lock 到版本库。
- 把
"monolog/monolog": "^2.9"改成"monolog/monolog": "2.9.1"(去掉^) - 执行
composer update monolog/monolog,确保composer.lock记录的是确切版本 - 立刻
git add composer.lock && git commit—— 手动编辑composer.lock会导致哈希校验失败 - 如果该包是间接依赖(没出现在 root 的
require里),只改composer.json没用,得配合replace或conflict
复杂点在于:你得先确认这个包到底是谁引入的。composer why monolog/monolog 能立刻告诉你依赖链,否则容易误删关键路径。没人帮你自动判断“不安全”和“不需要”的边界,得自己权衡。










