composer init 仅生成空壳 composer.json,不安装依赖、不创建 vendor 目录、不生成 autoload 文件;必须显式配置 autoload(如 psr-4)、合法 name(vendor/name)、type(project/library),并运行 composer validate 和 install 才能正常使用。

直接用 composer init,别碰 composer create-project —— 后者是抄模板的,不是初始化空项目。你想要一个干净、可控、能立刻进阶的起点,composer init 是唯一正解。
为什么 composer init 生成的 composer.json 不能直接跑?
它只写 JSON,不装包、不建 vendor/、不生成 vendor/autoload.php。常见错误现象:执行完就去 require 'vendor/autoload.php',报错 failed to open stream;或者类明明在 src/ 下,却提示 Class not found。
-
composer init后必须手动运行composer install才会创建vendor/和自动加载文件 - 如果
composer.json里没配"autoload",哪怕install成功,你的类也加载不了——vendor/autoload.php只负责加载你声明的命名空间 - 交互式流程中,“Would you like to define your autoload rules?” 这一步选
yes,再选PSR-4,输入类似App和src/,否则就得手改 JSON - 非交互模式下,
--autoload="psr-4:App=src/"是有效写法(注意反斜杠要单个,别写成双反斜杠)
composer.json 里 type 字段填错,autoload 就白配
默认值是 library,但绝大多数人初始化的是 CLI 工具、网站或脚本——这类项目该设为 project。填错会导致两个后果:一是别人 require 你的包时意外触发 autoload(不该被当库引用),二是某些工具(如 Symfony Flex)完全忽略你的配置。
- 本地应用/工具:显式写
"type": "project" - 打算发布成可被其他项目
require的通用库:才用"type": "library" -
type不影响composer install行为,但会影响composer dump-autoload是否生效、以及 Packagist 的兼容性检查 - 老项目接入 Composer 时,
type推荐统一设为project,除非你明确要把它做成 SDK 或组件
非交互初始化怎么写才不翻车?
参数漏一个,命令就失败;JSON 字符串引号不对,autoload 就解析失败。这不是“差不多就行”的事。
- 最小可用命令:
composer init --no-interaction --name="myorg/myapp" --author="Me" --require="php:^8.1" - 加 autoload 必须用单引号包裹整个 JSON 字符串:
--autoload='{"psr-4":{"App\":"src/"}}'(注意命名空间末尾的双反斜杠是转义需要) -
--require可多次使用:--require="guzzlehttp/guzzle:^7.8" --require="monolog/monolog:^3.0",不能合并 - 生成后立刻跑
composer validate:它能发现name缺 vendor 段、邮箱格式非法、JSON 语法错误等硬伤
老项目跑 composer init 为什么类还是加载不了?
它不会扫描你已有的文件,也不会猜你的命名空间。你填什么,它就信什么。
- 如果类文件在
lib/而不是src/,交互中 PSR-4 路径必须填lib/,填错就失效 - 已有类用了
MyApp命名空间,但 autoload 写成"MyApp": "src/"(少了个反斜杠),PHP 解析 JSON 时会报错,composer dump-autoload直接跳过这条规则 - 即使没依赖,也建议执行一次
composer install:它会生成基础vendor/autoload.php,之后你才能在入口文件里安全require - Windows 下目录名含空格,
composer init可能卡在包名推导,直接用--name跳过最省事
真正容易被忽略的点是:autoload 配置和 composer install 是两件事,缺一不可;而 type 字段一旦设错,后续调试成本远高于初始化时多敲几个字。











