composer licenses 命令仅显示当前项目顶层包的 license 字段值,如 myapp/myproject → MIT;它不展示任何依赖包的许可证信息,易被误认为可扫描全量依赖。

composer licenses 命令到底能查什么?
它**只显示当前项目顶层包(即你的项目本身)的 license 字段值**,不是所有依赖的许可证汇总。很多开发者误以为运行 composer licenses 就能一键扫出全部第三方库授权类型——这是常见误解。实际输出往往只有类似 myapp/myproject → MIT 这一行,和你预期的“全量依赖清单”完全不符。
真正有效的三种实操方式
要拿到每个已安装包的许可证信息,必须绕过 licenses 命令的局限,用以下任一方法:
-
推荐首选:
composer show --licenses—— 它会列出所有已安装包(含require-dev)的名称、版本和license字段值(如MIT、Apache-2.0),不递归但覆盖完整 vendor/ 目录; -
机器可读优先:
composer show --format=json | jq -r '.packages[] | select(.license != null) | "\(.name) \(.version) \(.license | join(", "))"'—— 用jq提取 JSON 中非空 license 字段,适合 CI 自动化; -
跳过 vendor,直读锁文件:
jq -r '.packages[] | select(.license != null) | "\(.name)\t\(.version)\t\(.license | join(" | "))"' composer.lock—— 不依赖vendor/是否存在,但可能漏掉未在 lock 文件中显式声明 license 的包。
为什么不能只信 license 字段?
Composer 不校验 license 字段是否符合 SPDX 标准,也不强制填写。你看到的可能是:
-
"license": "https://github.com/xxx/LICENSE"(填了 URL 而非标识符) -
"license": ["MIT", "proprietary"](多许可并存,需人工判断适用条款) -
license字段为空,但包根目录下有LICENSE.md(内容才是法律依据)
合规场景下,**必须结合源码仓库中的 LICENSE 文件正则匹配条款原文**,例如识别 GNU GENERAL PUBLIC LICENSE Version 3,否则仅靠字段值无法通过法务审核。
插件与工具:什么时候该用?
如果你需要导出 HTML 报告、生成 CSV 清单或做黑名单拦截(比如禁止 AGPL 包),建议用社区成熟工具:
-
composer require --dev terrapiq/composer-license-check,然后运行./vendor/bin/license-check,支持配置forbidden-licenses; -
composer global require zicht/composer-license-plugin,启用后可用composer licenses --format=html生成带链接的可读页面; - 注意:这些插件仍基于
composer.json中的license字段,**不会自动下载并解析 LICENSE 文件内容**,高合规要求项目仍需人工补查。
最常被忽略的一点:嵌套依赖的许可证可能比主依赖更严格。比如你用的 monolog/monolog 是 MIT,但它依赖的某个底层工具包是 AGPLv3——整条链路就受传染性条款约束。仅看顶层或直接依赖,根本发现不了这个风险。










