create-project 是拉取完整项目骨架而非创建空目录,它从 packagist 下载含 composer.json、public/ 和初始化脚本的预打包项目(如 laravel/laravel),真正的框架代码位于 vendor/laravel/framework 中。

create-project 不是“创建空项目”,而是拉取完整骨架
它不会新建一个空目录再让你填依赖,而是从 Packagist 上下载一个已打包好的、含 composer.json、public/、index.php 和初始化脚本的完整项目包。比如 laravel/laravel 本身就是一个可直接运行的项目,不是框架库——真正的框架代码在 vendor/laravel/framework 里。
常见错误现象:Could not find package vendor/name,往往不是拼写错,而是该包没发布到 Packagist、或只存在 dev-main 分支但你没加 --stability=dev;也可能是本地缓存损坏,先跑 composer clear-cache 再试。
- 目标目录必须为空,否则报错
Destination directory "xxx" is not empty.,--remove-vcs不解决这个问题 - 不能用本地路径或 Git URL 直接传给
create-project,要走--repository-url显式声明私有源 - 包的
composer.json必须有"type": "project",否则某些钩子(如post-create-project-cmd)可能被跳过
post-create-project-cmd 脚本为什么没执行
这个钩子只在**新生成项目的根级 composer.json 中定义才生效**,不是模板包自己 composer.json 里的脚本,更不是它某个 require 的依赖里写的。名称必须严格小写、带连字符:post-create-project-cmd,写成 PostCreateProjectCmd 或漏掉 - 都无效。
脚本执行时工作目录是新建项目根目录(如 my-app/),不是模板源码所在位置。所以别在脚本里写 ../template/init.php 这类路径——它找不到。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 如果脚本里用了
readline()或交互式输入,在 CI 环境下会卡住,加--no-interaction(或简写-n)才能继续 - 脚本失败不会中断整个命令,但后续步骤(如生成
.env)可能就没了,得手动补 - 想调试脚本执行过程?临时加
echo "running..." && exit 1到脚本开头,看是否真进了
--prefer-dist 是默认行为,但显式加上更稳妥
它让 Composer 优先下载压缩包(.zip/.tar.gz),而不是克隆 Git 仓库。速度快、不依赖 Git 客户端、网络更稳定。虽然新版 Composer 默认启用,但在 CI 或旧环境里,不加可能退化为 --prefer-source,导致下载慢甚至失败。
版本约束必须加引号包裹,尤其含 * 或 ^ 时,否则 shell 会提前解析通配符。比如 composer create-project laravel/laravel my-app 11.* --prefer-dist 在 zsh/bash 下大概率报错,正确写法是 "11.*"。
-
--stability=dev和"dev-main"不等价:前者放宽全局稳定性要求,后者指定具体分支,后者更精确 -
--no-scripts适合只想看骨架结构、跳过密钥生成或.env复制的场景,但之后要自己跑php artisan key:generate -
--keep-vcs保留.git,适合你想基于官方骨架做二次开发并提交 PR,但多数新项目应该删掉
什么时候不该用 create-project
如果你要建的是类库(library)、CLI 工具或微服务模块,而不是一个能直接 php -S 启动的 Web 应用,create-project 就是过度设计。它预设了 public/、入口脚本、环境配置这些应用层结构,类库项目反而会被污染。
这种场景下,composer init 才是正解:它只生成最小 composer.json,你来定义 autoload 规则、require-dev 和测试工具链。漏写 "type": "library" 不报错,但私有仓库平台或 PHPStan 可能拒绝索引。
- 团队协作中混用
init和create-project,会导致根目录结构不一致(有无public/、artisan、.env),CI 脚本得硬编码两套逻辑 - 私有模板若没配好
autoload的psr-4映射,create-project装完也跑不起来——命令不校验 autoload 是否可用,只管装 - 真正麻烦的从来不是命令语法,而是你是否信任那个模板包的
composer.json结构、脚本逻辑,以及你的 PHP 版本和扩展是否匹配它的require声明










