post-create-project-cmd 是 Composer 在 create-project 完成后执行的钩子脚本,仅当目标项目 composer.json 中明确定义该脚本时才触发,且必须为数组格式、在新项目根目录执行,失败则中断流程。

post-create-project-cmd 是什么,它真能自动执行脚本?
不是所有 composer create-project 都会触发 post-create-project-cmd —— 它只在目标项目 composer.json 中明确定义了该脚本时才生效。也就是说,这个钩子不是由你本地 Composer 启动命令决定的,而是由你要安装的那个包(比如 laravel/laravel)自己声明的。
常见误解是把它当成“我运行 create-project 时,我想让它干点啥”,但实际它是“那个模板项目想在我被创建出来后自动初始化”。如果你是模板维护者,才需要配置它;如果你只是使用者,得先确认对方 composer.json 里写了没。
怎么在模板项目中正确配置 post-create-project-cmd?
必须写在模板项目的根 composer.json 的 "scripts" 段里,且 key 名严格为 "post-create-project-cmd"(注意大小写和连字符):
{
"scripts": {
"post-create-project-cmd": [
"php -r \"copy('.env.example', '.env');\"",
"php artisan key:generate"
]
}
}
要点:
-
post-create-project-cmd值必须是数组(即使只有一条命令),不能是字符串 - 每条命令在项目目录(即新生成的项目根目录)中执行,路径上下文已切换完成
- 不支持
composer dump-autoload这类需依赖已安装 autoloader 的命令——此时 vendor 还没完全就位,部分 autoload 功能不可用 - 若某条命令失败(非零退出码),整个
create-project流程会中断,不会继续后续命令
为什么我的 post-create-project-cmd 没运行?常见排查点
最常踩的坑是:你在自己本地项目里加了这个钩子,然后执行 composer create-project myvendor/myproject,却发现没反应。原因很直接:myvendor/myproject 的 composer.json 里根本没写 post-create-project-cmd。
其他典型情况:
- 钩子写在了
require-dev依赖的包里 —— 不生效,只有目标项目自身的composer.json才算数 - 用了
--no-scripts参数(例如 CI 环境常用),会跳过所有脚本,包括这个钩子 - 命令里用了相对路径如
./artisan,但 Windows 下可能因换行符或权限问题失败;建议统一用php artisan - PHP 版本不匹配:钩子命令调用的
artisan或bin/console要求 PHP >= 8.1,而宿主机 PHP 是 7.4 —— 错误静默或报错但被忽略
替代方案:如果不能改模板,怎么实现类似效果?
当你只是使用者,又没法改模板源码(比如用的是官方 Laravel 或 Symfony 模板),但又想自动执行某些初始化动作,post-create-project-cmd 就无能为力了。这时更可靠的做法是手动补一步:
composer create-project laravel/laravel myapp && \ cd myapp && \ cp .env.example .env && \ php artisan key:generate
或者封装成 shell 函数、Makefile 目标,甚至写个简易 wrapper 脚本。硬要在 Composer 层面绕过限制去“注入”钩子,反而容易破坏可复现性 —— 比如不同人用不同 shell、不同 PHP CLI 配置,结果不一致。
真正要留意的是:这个钩子只跑一次,且只在项目诞生瞬间有效;后续 composer install 或 update 完全不触发它。别指望拿它做持续维护任务。


















