installed.json 是 Composer 安装后生成的已安装包元数据快照,记录 name、version、type、autoload、dist URL/shasum、source reference 等,不包含依赖树、require 关系、平台配置等;用于加速后续 install 和 autoload 生成。

installed.json 是 Composer 的本地安装快照
它不是配置文件,也不是运行时依赖解析依据,而是 composer install 或 composer update 执行完成后,Composer 自动生成的一份「当前已安装包的元数据快照」。它的存在只为一件事:让后续的 composer install(尤其在 CI/CD 或无锁文件场景)能跳过分析和下载,直接复现相同版本的安装结果。
它记录什么?不记录什么?
该文件位于 vendor/composer/installed.json,内容是 JSON 格式,核心字段包括:
-
name、version、type(如library)、autoload映射 —— 用于自动加载器生成 -
dist下的url和shasum—— 表明该包是从哪个归档下载的,以及校验值 -
source下的reference(如 commit hash)—— 对 Git 包有效,表示检出的具体提交 - 不包含 依赖树结构、require 关系、平台配置(PHP 版本等)、脚本定义或插件逻辑
为什么有时候它会缺失或内容异常?
常见触发场景和应对方式:
- 执行了
composer install --no-install或--no-scripts—— 这些选项本身不影响installed.json生成;但若中途失败(如网络中断、权限不足写入vendor/),文件可能为空或残缺 - 手动删了
vendor/却没重新install—— 文件自然消失,下次install会重建 - 用了
composer install --ignore-platform-reqs但实际 PHP 版本不兼容某包 —— 安装可能卡在 autoload 生成阶段,导致installed.json写入不全 - 多个 Composer 实例并发写入同一 vendor 目录(如并行构建)—— 可能引发文件覆盖或 JSON 格式损坏
它和 composer.lock 的关系与分工
两者都服务于可重现安装,但角色不同:
-
composer.lock是「源码级声明」:记录所有依赖的精确版本、哈希、来源,供install读取并决策「该下什么」 -
installed.json是「结果级记录」:只在安装成功后生成,反映「实际上装了什么」,供autoload_dump()、插件钩子或调试工具读取 - 删掉
lock文件再install,installed.json仍会生成,但内容取决于当前解析出的最新兼容版本 —— 它不保证与之前一致
真正容易被忽略的是:某些自定义 Installer 或 Capistrano 部署脚本会直接读取 installed.json 来判断扩展是否启用,一旦该文件因权限或中断未完整写入,这类逻辑就会静默失败。










