composer create-project 是模板实例化而非包管理,它克隆完整项目(含文件结构和自动初始化),仅支持 type=project 的包,通过 post-create-project-cmd 执行初始化脚本,不覆盖非空目录。

create-project 不是安装依赖,而是克隆一个完整项目
它和 composer require 有本质区别:后者往现有项目里加库,前者是从头拉一个「能直接跑的项目副本」。比如你执行 composer create-project laravel/laravel myapp,Composer 并不会只写个 composer.json 然后装包——它会从 Packagist 找到 laravel/laravel 对应的发布包(通常是 zip 压缩包),解压全部文件(含 app/、routes/、artisan 等),再进目录自动运行 composer install。
- 整个过程相当于手动 git clone + composer install + 初始化脚本,但全自动
- 模板包必须是
"type": "project"类型(如laravel/laravel、symfony/skeleton),普通库包("type": "library")不支持 - 如果目标目录已存在且非空,命令会直接报错退出,不会覆盖
它怎么触发初始化动作?靠 post-create-project-cmd 脚本
很多框架模板会在自己的 composer.json 里定义 "post-create-project-cmd" 钩子,比如 Laravel 就用它自动生成 APP_KEY、重命名 .env.example 为 .env。这个脚本在 composer install 完成后立即执行。
- 如果你不想让它运行(比如想跳过密钥生成做自动化部署),加
--no-scripts - 钩子失败会导致整个命令中断,所以模板作者通常会加错误处理,比如用
@php -r "copy('env.example', '.env') ?: print('skip .env copy');" - 注意:这个钩子只在
create-project时触发,composer install或update不会调用
--prefer-dist 和 --prefer-source 到底选哪个?
默认行为是优先走 --prefer-dist(下载 zip 包),速度快、不依赖 Git;而 --prefer-source 会尝试 clone Git 仓库,适合你要改框架源码或调试内部逻辑。
-
--prefer-dist:适合绝大多数场景,尤其是 CI/CD 或生产环境初始化 -
--prefer-source+--keep-vcs:组合使用才能保留.git目录,方便后续提交或切分支 - 某些私有模板没发 dist 包(只推了 Git tag),此时即使加
--prefer-dist也会 fallback 到 source
常见卡点和绕过方式
最常遇到的是网络慢、权限错、版本不匹配——不是命令本身复杂,而是环境链路太长。
- 卡在 “Installing dependencies”:先试
-vvv看具体卡在哪一步;国内用户务必配镜像:composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
- “Could not find package”:检查包名是否拼错,或版本号格式不对(比如写成
10.x而不是"10.*",引号不能少) - PHP 版本不兼容:用
--ignore-platform-reqs强行过,但不推荐;更稳妥的是先确认模板文档要求的 PHP 版本,再调环境 - 想把项目建到当前目录(不新建文件夹):目录名填
.,但当前目录必须为空,否则报错
create-project 的本质是「模板实例化」,不是「包管理」**。它依赖模板包自身是否健壮——如果那个 composer.json 里漏写了 autoload、scripts 写死路径、或 post-create-project-cmd 没做容错,你拿到的就是一个半残项目。所以选模板时,别只看 star 数,得看它的 composer.json 和最近 release 是否干净。










