Composer 没有内置 licenses 命令,运行会报错;唯一官方支持方式是 composer show,推荐用 composer show --recursive --format=json | jq -r '.[] | "(.name) (.version) (.license // "UNKNOWN")"' 全量提取。

Composer 没有内置的 licenses 命令,直接运行会报错 Command "licenses" is not defined.。所有声称“原生支持 composer licenses”的教程或文档,要么基于已废弃的第三方插件,要么混淆了版本差异——当前(2026年)稳定、无需额外安装、且被 Composer 官方维护的方式只有一种:用 composer show。
为什么 composer licenses 不可靠
这个命令从未进入 Composer 官方核心功能列表。你在不同资料里看到的输出示例(比如带 Name/Version/License 三列的表格),实际来自社区插件(如 zicht/composer-license-plugin)或早期已被移除的实验性 PR。2025 年底起,主流 CI 流水线已普遍剔除对该命令的依赖,因为:
- 它不随 Composer 二进制分发,必须手动
composer require --dev zicht/composer-license-plugin - 插件解析逻辑依赖
vendor/目录结构,而很多构建环境(如 Docker 多阶段构建)根本不会保留vendor/ - 插件读取的是
composer.json中的license字段,和真实 LICENSE 文件内容无校验关系
composer show --licenses 是什么?它还在吗?
该参数在 Composer 2.5+ 中已被彻底移除。如果你的 composer --version 输出是 2.5.0 或更高,运行 composer show --licenses 会直接报错 Unrecognized option: --licenses。它曾短暂存在(2.2–2.4.x),但因字段语义模糊、不递归、且与 SPDX 标准脱节而被弃用。
现在唯一兼容全版本(2.1.12+ 起)、无需插件、能真正展开依赖树的方式是:
composer show --recursive --format=json | jq -r '.[] | "\(.name) \(.version) \(.license // "UNKNOWN")"'
注意:--recursive 是关键——没有它,composer show 只查 composer.json 直接声明的包,漏掉全部子依赖(比如 symfony/console 依赖的 psr/log 就不会出现)。
从 composer.lock 直读许可证(CI 友好方案)
当你的 CI 环境不允许或不希望执行 composer install(比如仅做合规扫描,不想下载几百 MB 依赖),应跳过 vendor/,直接解析 composer.lock:
jq -r '.packages[] | select(.license != null) | "\(.name)\t\(.version)\t\(.license | join(" | "))"' composer.lock
这条命令的优势:
- 不依赖
vendor/是否存在,composer.lock提交即生效 - 字段来源是 lock 文件中固化的内容,比运行时读
vendor/更稳定 - 但要注意:某些包在
composer.json里没填license,lock 文件里对应字段就是null,这类必须人工查其 GitHub 仓库根目录下的LICENSE文件
常见陷阱:.license 字段可能是字符串("MIT")、数组(["MIT", "Apache-2.0"])或空值。用 jq 处理时别硬写 .license[0],要用 .license // "UNKNOWN" 或 .license | join(" | ") 安全展开。
license 字段为空或写成 URL 怎么办?
看到 "license": "https://github.com/xxx/LICENSE" 或 "license": "proprietary",不能直接采信。SPDX 标准要求使用规范标识符(如 MIT、GPL-3.0-only),而非链接或模糊描述。
此时你必须:
- 用
composer show vendor/package-name查看该包实际安装路径 - 进入对应
vendor/vendor/package-name/目录,检查是否存在LICENSE、LICENSE.md或COPYING - 若不存在,去 Packagist 页面点开 “Source” 链接,跳转到 GitHub/GitLab 仓库,看根目录下 LICENSE 文件内容
- 特别注意多许可证场景:
["MIT", "Apache-2.0"]≠MIT OR Apache-2.0—— 前者语义不明,后者才是 SPDX 合法表达,法务审核时会被打回
最易被忽略的一点:很多团队把许可证检查写成 CI 脚本后就以为万事大吉,但没建立人工复核机制。只要 license 字段是 unknown、proprietary、URL 或非 SPDX 标识符,就必须走人工确认流程,不能靠脚本自动放行。


















