应优先用 composer init 初始化空项目,它仅生成干净的 composer.json;create-project 适合快速搭建完整框架项目但易污染结构。

composer create-project 能直接建项目,但别乱用 –prefer-dist
它确实能一步生成带 vendor 的完整项目,比如 Laravel:composer create-project laravel/laravel myapp。但问题在于——如果你只是想初始化一个空项目(比如写个工具库),create-project 会硬拉下整个框架骨架,还可能执行 post-create-project-cmd 脚本,污染你的初始结构。
真正该用的命令是:composer init。它只问你包名、描述、依赖等,最后生成干净的 composer.json,不碰 vendor,也不下载任何包。
- 运行前确保当前目录为空,否则
init可能报错说“目录非空” - 如果跳过交互式提问,加
-n参数,再用--name等显式指定,比如:composer init --name="myorg/mypkg" --description="A CLI tool" -n -
create-project默认用–prefer-dist(下 zip 包),但在 CI 或内网环境可能因没配置 GitHub token 导致限流失败;此时换成–prefer-source更稳
composer.json 里 type 字段不是可有可无的
很多新手初始化后直接开写,结果发现 composer install 不装 require-dev,或者 autoload 不生效——八成是 type 没设对。
这个字段决定 Composer 怎么处理你的包:是库(library)、应用(project)还是插件(wordpress-plugin)。默认值是 library,但如果你初始化的是 CLI 工具或网站项目,建议显式写上:
{
"name": "myorg/myapp",
"type": "project",
"autoload": { "psr-4": { "App\": "src/" } }
}
-
type: "project"表示这是最终可运行的应用,Composer 不会把它当依赖去安装(避免被别人require时误触发自动加载) -
type: "library"才会启用autoload规则供其他项目引用;漏写会导致composer dump-autoload后类还是找不到 - 某些工具(如 Symfony Flex)会根据
type自动启用配方(recipes),设错就收不到自动配置
为什么 composer install 报 “Your requirements could not be resolved”?
这不是网络问题,也不是权限问题,而是 composer.json 里 require 和 PHP 版本约束打架了。常见于初始化后随手加了个新包,没检查兼容性。
比如你在 PHP 8.1 环境下初始化项目,然后加了 "monolog/monolog": "^1.0" —— 这个老版本只支持到 PHP 7.4,Composer 就会死锁,因为找不到满足所有条件的版本组合。
- 先跑
composer show --platform看当前环境真实支持的 PHP 和扩展版本 - 加依赖时用
composer require monolog/monolog:^2.0,让 Composer 自动选兼容版本,别手写旧版号 - 如果必须用旧包,就显式锁定 PHP 版本:在
composer.json加"config": { "platform": { "php": "7.4.33" } },但这只是骗过检查,实际运行仍可能出错
composer.json 初始化后,这些字段别急着删
交互式 composer init 会生成一堆字段,比如 license、authors、minimum-stability。有人觉得“反正自己用”,全删了省事——结果后续 require 私有包或提交 Packagist 时卡住。
-
license是必需字段,缺失会导致 Packagist 拒绝收录,CI 构建时某些扫描工具也会告警 -
minimum-stability默认是stable,删掉后 Composer 会按规则降级为dev,可能意外装入dev-master分支,导致行为不稳定 -
authors看似无关,但很多 IDE(如 PHPStorm)靠它识别包归属,补全时优先显示同作者的其他包
初始化只是起点,composer.json 不是填完就封存的表单,它是项目生命周期里持续被读取的契约文件。少一个字段,后面就可能多一个没人想到的隐性约束。










