composer show 是唯一稳定可靠的原生命令,它读取本地 vendor/ 下已安装包的 composer.json 中 license 字段,支持通配符和 json 格式输出,配合 jq 或 php 脚本能准确提取许可证信息,但需人工核验 license 文件内容与 spdx 标识符一致性。

composer show 是唯一靠谱的原生命令
Composer 没有 composer license、composer licenses 或 composer show --licenses(该参数在 2.5+ 已移除),直接运行这些命令只会得到 Command "xxx" is not defined.。唯一稳定、无需插件、不依赖外部服务的方式,就是用 composer show 查单个包或批量导出后解析。
-
composer show vendor/package-name输出最权威的license字段值——它读的是本地vendor/下已安装包的composer.json,不是 Packagist 缓存,也不是 lock 文件 - 必须先执行过
composer install,否则vendor/为空,show会报Package not found - 支持通配符:比如
composer show monolog/*能一次看全 monolog 生态包 - 若包未声明 license,字段可能为空、为
proprietary,或写成SEE LICENSE IN LICENSE.md——此时show照样输出,但你得手动打开对应文件核对全文
批量提取 license 信息:JSON + jq 是最稳的自动化路径
想一次性看清所有包的协议,别信“composer show --all | grep license”这种管道拼凑——它错行、漏字段、无法处理数组型 license(如 ["MIT", "Apache-2.0"])。机器可读场景下,必须走 JSON 流程。
- 用
composer show --format=json输出结构化数据,再交给jq处理:composer show --no-dev --format=json | jq -r '.packages[] | "\(.name) \(.license // "UNKNOWN")"' - 注意加
--no-dev:生产环境部署前要排除require-dev包,避免把 PHPUnit 的 MIT 当成 runtime 依赖 -
.license // "UNKNOWN"是关键——它兜底处理 null 或缺失字段,比grep更可靠 - 如果没装
jq,可用 PHP 脚本替代(Composer 环境自带):读composer.lock并对$pkg['license'] ?? ['unknown']强转数组再展开,能覆盖 license 字段缺失的情况
别只信 license 字段:SPDX 标识符 + LICENSE 文件必须双验证
看到 "license": "MIT" 不等于合规。这个字段只是元数据,法律效力来自项目根目录的 LICENSE 或 LICENSE.md 文件内容,且必须匹配 SPDX 官方列表。
-
"MIT License"、"The MIT License"、"mit"都是无效值——Packagist 不识别,合规工具会标红;正确写法只有"MIT" - 多许可证必须用 SPDX 允许的逻辑连接符:
"MIT OR Apache-2.0"✅,["MIT", "Apache-2.0"]❌(JSON 数组格式在旧版 Composer 中会被截断) - 有些包在
composer.json声明了"license": "BSD-3-Clause",但实际发布版本的composer.lock里仍是null——因为作者没同步更新 Packagist 元数据,此时仅靠自动化脚本无法发现 - 遇到
proprietary、unlicensed、see license in license.md,必须人工打开源码仓库,确认 LICENSE 文件是否真实存在、内容是否与声明一致
真要生成合规报告?插件比手写脚本更省事
内部审计或交付给法务时,纯命令行输出太简陋。这时候推荐社区插件 zicht/composer-license-plugin,它不只是补了个 composer licenses 命令,关键是做了启发式识别。
- 安装后运行
composer licenses --format=html,会生成带超链接的页面,点包名就能跳转到 Packagist,点 license 就能展开 LICENSE 文件全文 - 对
license字段为空的包,它会自动读取vendor/xxx/LICENSE*文件内容,用关键词匹配(如检测到Copyright (c) [year]+Permission is hereby granted...就标为 MIT) -
--format=json输出含licenseText和isStandard字段,方便集成进 CI 流水线做自动拦截(例如禁止GPL-2.0-or-later出现在闭源产品中) - 但它不能替代法律审查:比如某包写的是
"MIT",LICENSE 文件里却悄悄加了“不得用于军事用途”的例外条款——这种非 SPDX 语义,插件和所有自动化工具都识别不了
最容易被忽略的点是:license 字段声明、SPDX ID、LICENSE 文件内容、实际分发场景这四者必须一致。差其中任意一环,都可能在产品上线后触发合规风险。工具只能帮你查“写了什么”,没法替你判断“能不能用”。










