composer show --licenses只显示顶层包,因为它默认不递归扫描vendor/目录,仅读取composer.json中直接声明的依赖;而composer licenses --no-dev --format=json才是能覆盖全部已安装包(含子依赖)并输出结构化数据的可靠命令。

composer show --licenses 为什么只显示顶层包?
因为 composer show --licenses 默认只列出 composer.json 中直接声明的依赖,不递归展开 require-dev 或嵌套依赖。你看到的清单往往漏掉几十个 transitive dependency(比如 monolog/monolog 依赖的 psr/log),实际项目里真正要合规审计的是全部闭包依赖。
用 composer licenses --no-dev 导出完整许可证树
composer licenses 是 Composer 2.2+ 内置命令,比 show --licenses 更可靠。它默认递归扫描整个 vendor/ 目录,生成所有已安装包的许可证信息:
- 加
--no-dev排除开发依赖(如phpunit/phpunit),避免把测试工具的 MIT 许可混进生产合规清单 - 加
--format=json输出结构化数据,方便后续解析或导入 SPDX 工具 - 不加
--strict时,对缺失许可证的包会标为unknown;加了则直接报错退出,适合 CI 强制校验
示例命令:
composer licenses --no-dev --format=json > licenses.json
许可证字段为空或显示 unknown 怎么办?
常见原因有三类:
- 包作者没在
composer.json的license字段填值(比如写成"license": []或留空) - 包用了非标准许可证标识(如
"license": "BSD-3-Clause-Clear"),Composer 无法映射到 SPDX ID - 本地
vendor/不完整(比如用composer install --no-dev装过,但后来手动删了某些目录)
验证方式:找一个显示 unknown 的包,进 vendor/{vendor}/{package}/composer.json 查看原始 license 字段;若为空,就得联系上游补全,或人工核查其 README.md 或 LICENSE 文件。
导出后如何快速识别高风险许可证?
不用肉眼扫 JSON —— 直接 grep 关键词:
-
grep -i "gpl\|affero\|copyleft" licenses.json找 GPL 类强传染性协议 -
grep -i "unlicense\|public domain" licenses.json标记无限制许可(需确认是否真为 Public Domain) - 注意
"license": "MIT OR Apache-2.0"这种多选许可,必须同时满足两者条款
真正麻烦的不是 MIT、Apache 这些常见许可,而是那些拼写不规范的自定义许可证文本(比如 "license": "BSD-like"),它们不会出现在 SPDX 列表里,得逐个打开源码仓库看 LICENSE 文件原文。


















