composer.json是运行时配置契约,name字段必须为小写vendor/name格式,否则install直接失败;type决定安装行为,description等仅用于Packagist展示,不参与逻辑解析。

composer.json 不是文档占位符,而是一份运行时配置契约——它直接决定类怎么加载、依赖怎么解析、脚本怎么触发、甚至项目能否被其他包引用。填错字段不是“文档没写好”,而是可能让 new 报 Class not found、composer install 静默失败、或 CI 构建卡在依赖冲突上。
为什么 name 字段填错会导致 install 直接失败
Composer 用 name 做包唯一标识,不是显示用的标签。它必须严格满足 vendor/package 格式,全小写、仅含短横线、斜杠分隔:
-
"name": "myorg/my-tool"✅ -
"name": "MyOrg/MyTool"❌(大写) -
"name": "my_org/my_tool"❌(下划线) -
"name": "mytool"❌(缺 vendor 段)
一旦不合规,composer install 会立即报错:Invalid package name "xxx": package names must be lowercase...。本地测试也绕不开——composer validate 就会拦截。
autoload.files 和 psr-4 混用时谁优先
autoload.files 是无条件预加载,psr-4 是按需加载;两者共存时,classmap(若存在)和 files 条目在自动加载链中优先级更高。
-
autoload.files里的文件会在每次require 'vendor/autoload.php'时执行,哪怕只是启动一个 CLI 命令 -
psr-4映射必须以反斜杠结尾:"App\": "src/",漏掉会导致命名空间完全不匹配 -
classmap扫描结果固化在vendor/composer/autoload_classmap.php中,改了源文件不重跑composer dump-autoload就不会更新
验证是否生效?别只看 composer install 成功——手动 new 一个类,或 var_dump(class_exists('AppFoo')) 才算数。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
require-dev 为什么在 CI 里容易引发构建失败
require-dev 的包不会出现在生产环境,但它的版本约束会写进 composer.lock。CI 执行 composer install --no-dev 时,Composer 仍会校验 lock 文件中 dev 包引入的间接依赖是否与 require 冲突。
- 例如:
phpunit/phpunit拉入symfony/console:^5.0,而你的require锁定了symfony/console:^6.0,composer install --no-dev可能失败 - 查冲突用:
composer why-not symfony/console:6.0 - CI 脚本务必加
--prefer-dist,避免因本地vendor/状态污染判断
更隐蔽的问题是:某些 require-dev 包(比如 laravel/framework)会覆盖运行时行为,导致本地能跑、CI 报错,却查不出原因。
description 和 keywords 字段的真实作用边界
description 只用于 Packagist 搜索摘要,长度被截断到约 120 字;keywords 影响搜索排名,但填 ["php", "tool"] 这类泛词反而降低曝光。
- 安装说明必须放根目录
README.md——GitHub、GitLab、IDE、Packagist 页面都自动渲染它 -
support字段里的issues或sourceURL 填错,用户点进去就是 404,但不影响安装 - 想固化命令?用
scripts,并在注释里写清楚用途,例如:"post-install-cmd": "@php artisan migrate --force // only in dev"
最容易被忽略的是:所有这些字段都不参与自动加载或依赖解析逻辑,乱塞内容不会报错,但会让维护者误判配置意图——尤其是当别人接手项目时。

















