composer没有export命令,导出依赖应使用composer show配合重定向或直接解析composer.lock文件;后者更权威、快速且不受php环境限制。

composer export 会失败?因为根本没这个命令
Composer 没有 composer export 或 composer list-dependencies 这类内置命令。你想导出依赖清单,实际要靠 composer show 配合输出重定向,或者用 composer lock 文件本身——它已经是结构化依赖快照。
常见错误现象:composer export 报错 Command "export" is not defined;或误以为 composer dump-autoload 能生成依赖列表,其实它只刷新自动加载映射。
-
composer show --tree查看带层级的依赖树(适合人工阅读) -
composer show --format=json输出 JSON(适合脚本解析) - 直接读取
composer.lock——它比composer.json更权威,记录了确切版本、哈希与 require 关系
导出扁平依赖列表:用 show + grep 最快
想快速得到一行一个包名+版本的纯文本清单(比如给安全扫描或审计用),composer show 加管道最直接。注意它默认只显示直接依赖,加 --all 才包含全部递归依赖。
使用场景:CI 中生成依赖摘要、对比两个环境的差异、导入到第三方工具。
composer show --all --no-ansi | awk '{print $1 "@" $2}' | sort > deps.txt- 如果只要包名(不含版本):
composer show --all --no-ansi | awk '{print $1}' | sort -u > packages.txt -
--no-ansi防止颜色控制符污染输出;不加可能在非终端环境下报错或混入乱码
依赖版本不一致?别信 composer.json,盯紧 composer.lock
composer.json 是声明式需求,composer.lock 才是真实安装结果。导出清单时若忽略 lock 文件,会导致“理论上该装什么”和“实际上装了什么”脱节——尤其当用了 ^ 或 ~ 版本约束时。
性能 / 兼容性影响:直接解析 composer.lock 比运行 composer show 快得多(无 autoload 初始化开销),且不依赖当前 PHP 环境是否能完整加载所有包。
-
jq -r '.packages[] | "\(.name)@\(.version)"' composer.lock | sort > lock-deps.txt(需安装jq) - PHP 原生解析:
php -r '$l = json_decode(file_get_contents("composer.lock"), true); foreach($l["packages"] as $p) echo $p["name"]."@".$p["version"]."\n";' | sort > lock-deps.txt - 注意
composer.lock中的packages-dev是开发依赖,生产环境导出时通常要排除
为什么 vendor/autoload.php 不能用来导出依赖?
有人试图通过遍历 vendor/composer/autoload_*.php 或反射已加载类来反推依赖,这不可靠。原因很实在:不是所有包都会注册自动加载规则(比如只含 bin 脚本的包),有些包甚至根本不含 PHP 类。
容易踩的坑:在 CI 中用 get_declared_classes() 或 get_included_files() 做依赖发现,结果漏掉 phpunit/phpunit 这类只在测试时 require 的包,或把 symfony/polyfill 这类条件加载的包算错。
- 依赖关系必须从声明(
composer.json)或锁定(composer.lock)中读取,而不是运行时状态 - Composer 的依赖解析发生在 install/update 阶段,跟 runtime 无关
- 如果你真需要运行时依赖图,得用
composer show --tree,但它仍基于 lock,而非 autoloader
真正麻烦的地方在于:lock 文件里包的顺序不固定,不同 Composer 版本生成的字段可能微调(比如 dist.shasum 在新版里改叫 dist.reference),写脚本解析时得预留兼容层。










