composer licenses 命令仅显示项目自身 license 字段,不扫描依赖;应使用 composer show --licenses 查看全部依赖许可证,它读取 vendor 中各包 composer.json 的 license 字段,支持 JSON 输出与 jq 处理。

composer licenses 命令并不能可靠查看所有依赖的许可证——它只显示你项目顶层 composer.json 里的 license 字段,不是 vendor 里几百个包的汇总。 这是绝大多数人踩的第一个坑:运行完命令只看到一行 myapp/myproject → MIT,误以为“全量扫描完成”,实际连一个依赖都没扫到。
为什么 composer licenses 输出这么少?
这个命令设计上就只读取当前项目的 composer.json,不递归、不查 vendor/、也不解析 composer.lock。官方文档没写清楚,但多个权威来源(包括 2026 年初的实测反馈)都确认:它本质是个“项目自报许可证”功能,不是依赖审计工具。
- 它不关心
monolog/monolog或symfony/http-foundation用的是 MIT 还是 GPL - 即使你加了
--format=json或--verbose,输出内容也不会变多 -
--no-dev和--short在这里也无效——因为根本没在处理依赖
真正能列出全部依赖许可证的命令是 composer show --licenses
这才是你应该记住并加入 CI 脚本的主力命令。它扫描整个 vendor/ 目录,读取每个已安装包的 composer.json 中的 license 字段,覆盖 require 和 require-dev 全部包。
- 输出格式为:
package/name version license(例如guzzlehttp/guzzle 7.8.1 MIT) - 支持
--format=json,方便后续用jq过滤或统计:composer show --licenses --format=json | jq -r '.[] | select(.license != null) | "\(.name) \(.license)"' - 如果某包
license字段为空或填了 URL(如"https://github.com/foo/LICENSE"),它会显示unknown,这时必须人工查源码仓库
绕过 vendor:直接从 composer.lock 提取许可证(适合无 vendor 环境)
CI 构建时有时还没执行 composer install,vendor/ 不存在,但 composer.lock 一定有。此时可用 jq 直接解析:
jq -r '.packages[] | select(.license != null) | "\(.name)\t\(.version)\t\(.license | join(" | "))"' composer.lock
注意两点:
- 它可能漏掉 license 字段没写进 lock 文件的包(比如某些旧版 Composer 或手动修改过的 lock)
- 字段值仍是字符串,无法自动识别
["MIT", "proprietary"]中哪个适用,也不能把Apache-2.0和Apache License, Version 2.0归一化
真正的合规检查永远不止看字段:MIT 写得再标准,也得确认源码根目录下 LICENSE 文件是否真为 MIT 正文;GPL 包哪怕字段写成 unknown,只要 LICENSE 文件里有 “GNU GENERAL PUBLIC LICENSE Version 3”,法务就不会放过。所以 composer show --licenses 是起点,不是终点。










