composer init 仅生成空 composer.json,不安装依赖或配置自动加载;Package name 必须为全小写 vendor/name 格式,目录名不可含空格或特殊字符;PSR-4 需手动配置且路径与命名空间严格对应,否则类无法加载;require 与 require-dev 不可错放,type 应按项目性质设为 "project" 或 "library"。

composer init 不是“创建项目”,它只生成一个空壳 composer.json,不装包、不建 vendor/、不配自动加载——漏掉任一关键配置,后续必报 Class not found 或 failed to open stream。
Package name 必须是 vendor/name 格式,否则直接卡死
交互式运行 composer init 时,第一步 “Package name” 输入 myapp 或 MyApp 会立刻报 Invalid package name。Composer 强制要求全小写、含斜杠、不含空格/中文/下划线/大写字母。
- 目录名含空格(
My Project)或特殊符号(my-app!),init 会卡住——先重命名目录,或用--name="myorg/myapp"跳过 - Git 用户名带中文或空格,可能被自动读取为非法包名,建议一律显式传
--name -
local/mytool是合法的本地项目名;myorg/myapp比myorg_myapp安全得多
autoload 不手动加 PSR-4,类永远找不到
交互流程里问 Would you like to define your autoload rules?,选 yes 后只支持 classmap,**不支持 PSR-4**——这是长期存在的设计限制。你写了 src/Hello.php 并声明 namespace App;,不手动加配置,composer dump-autoload 就不会注册任何映射。
- 非交互模式下必须整段 JSON 传入:
--autoload='{"psr-4":{"App\":"src/"}}'(注意双反斜杠是 JSON 转义必需) - 路径
"src/"必须真实存在,且相对于composer.json所在目录;写成"./src/"或绝对路径全部无效 - 命名空间末尾的反斜杠不能少:
"App\"正确,"App"或"App\\"都会导致class_exists()返回false
require 和 require-dev 放错位置,上线就静默炸
这不是“本地能跑就行”的问题,而是部署一致性契约。composer install --no-dev 会严格按字段删包,放错位置等于主动拆弹。
-
guzzlehttp/guzzle进require-dev→ 上线后所有 HTTP 请求失败 -
phpunit/phpunit进require→ 生产环境白装几十 MB,还可能因版本冲突导致install失败 - 搜你代码里所有
use和new:出现在src/或app/的类,对应依赖进require;只在tests/、bin/或 CI 脚本里出现的,进require-dev
type 字段填错,autoload 白配、CI 白跑
默认值是 "library",但绝大多数人初始化的是 CLI 工具、网站或脚本——这类项目该设为 "project"。填错会导致两个后果:一是别人 require 你的包时意外触发 autoload(不该被当库引用),二是某些工具(如 Symfony Flex)完全忽略你的配置。
- 本地应用/工具:显式写
"type": "project" - 打算发布成可被其他项目
require的通用库:才用"type": "library" -
type不影响composer install行为,但会影响composer dump-autoload是否生效、以及 Packagist 的兼容性检查
最常被忽略的其实是路径与命名空间的严格对应关系:哪怕 autoload 配对了、dump-autoload 也跑了,只要 src/App/Service/Logger.php 里写的是 namespace App; 而不是 namespace AppService;,照样 Class not found。这不是 Composer 的 bug,是 PSR-4 规则本身的要求。


















