运行时读取当前 Composer 包版本最可靠方式是解析 vendor/composer/installed.json(v2)或 installed.php(v1),通过匹配包名提取 version 字段,而非依赖 composer.json 的 version 或 Package::getVersion() 等不可靠方法。

如何在运行时读取当前 Composer 包的版本号
Composer 本身不提供运行时 API 直接暴露当前包版本,composer.json 中的 version 字段在安装后不会自动注入到 PHP 运行环境中。你不能靠调用某个函数直接拿到“当前包版本”,必须依赖外部机制——最可靠的是读取 composer.lock 或利用 Composer 自动生成的 vendor/composer/installed.json(v2)或 vendor/composer/installed.php(v1)。
读取 vendor/composer/installed.json 获取本包版本(推荐)
Composer v2 默认生成 JSON 格式的安装元数据,路径为 vendor/composer/installed.json,其中包含所有已安装包的名称、版本、源类型等信息。你需要按 name 字段匹配当前包名(即 composer.json 中的 "name": "vendor/name"),再提取其 version。
实操建议:
- 先通过
__DIR__ . '/../../composer.json'或getcwd() . '/composer.json'读取当前项目根目录的composer.json,解析出name字段;但更稳妥的方式是硬编码包名(因为运行时可能被作为依赖引入,composer.json不一定在上层) - 检查
file_exists(__DIR__ . '/../../vendor/composer/installed.json'),避免在开发环境未装依赖时报错 -
installed.json中的version是规范后的版本(如dev-main、1.2.3+commitabc),不是composer.json原始字符串 - 注意:该文件内容由 Composer 维护,结构稳定,但字段层级较深——需遍历
packages数组(v2)或packages对象(v2 的 JSON 是数组)
$installed = json_decode(file_get_contents(__DIR__ . '/../../vendor/composer/installed.json'), true);
$myPackageName = 'myvendor/mypackage';
$version = null;
foreach ($installed['packages'] as $pkg) {
if ($pkg['name'] === $myPackageName) {
$version = $pkg['version'];
break;
}
}
echo $version; // e.g. "dev-main" or "2.1.0"
兼容 Composer v1 的 fallback:读 vendor/composer/installed.php
v1 时代 Composer 生成的是 PHP 文件,返回一个大型数组,结构不同且无命名空间隔离。如果你的包需支持旧项目,得做兼容判断。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
常见错误现象:
- 直接 require
installed.php导致全局变量污染或重复定义警告(它用return [...],但某些 autoload 场景下可能被多次加载) - v1 的
installed.php中包信息在$installed['versions']下,键是带vendor/name的字符串,值数组里有pretty_version和version两个字段,语义略有差异 - 不要用
class_exists()或function_exists()判断 Composer 版本——应优先检测文件存在性与内容格式
性能影响很小,但每次读文件会触发 I/O,建议加单例缓存或仅在必要时(如日志、调试)调用。
为什么不用 Package::VERSION 或常量?
有人试图在 composer.json 里写 "autoload": { "files": ["version.php"] } 并手动维护常量,这看似简单,但极易脱节:
- CI/CD 构建时若未同步更新
version.php,运行时版本就错 - Git tag 推送后 composer install 不会自动更新常量,而
installed.json每次 install/update 都重写 - 使用
composer dump-autoload --optimize后,files加载顺序可能受影响,导致常量未定义 - 私有包打
dist包时,version.php若未包含进 ZIP,就彻底失效
所以,依赖 Composer 自身生成的元数据才是唯一可信来源。复杂点在于要处理 v1/v2 差异和路径定位,但逻辑清晰、无需人工干预。

















