结论:post-create-project-cmd 是 Composer 官方支持的钩子,但仅在 composer create-project 执行时、且由被安装包的 composer.json 声明才生效;在本地项目中配置它并运行 install/update 不会触发。

直接说结论: post-create-project-cmd 不是 Composer 的内置钩子,它根本不存在——你看到的文档或配置里写了这个,大概率是抄错了、拼错了,或者混淆了 post-create-project-cmd 和正确的 post-create-project-cmd?等等,再确认一遍:Composer 官方只定义了 post-create-project-cmd 吗?不,官方根本没有这个钩子。
Composer 官方支持的项目创建后钩子只有 post-create-project-cmd
这是最常被搞混的一点。很多人在 composer.json 里写:
"scripts": {
"post-create-project-cmd": ["@php build/setup.php"]
}
结果死活不执行——因为这行脚本永远不会被触发。Composer 实际识别的钩子名是:
-
post-create-project-cmd✅(注意是cmd,不是command) - 但更关键的是:它只在运行
composer create-project时,且仅当目标包的composer.json中声明了该脚本时才生效
也就是说:这个钩子不是“你在自己项目里配了就能用”,而是“你发布的包(比如一个 Laravel starter 模板)在别人用 create-project 安装它时,它的 composer.json 里写了这个脚本,才会执行”。
常见错误现象:
- 在自己本地项目的
composer.json里加post-create-project-cmd,然后运行composer install或composer update—— 完全没反应 - 复制了某模板仓库的配置,但没注意那个模板是作为
create-project目标发布的,而你只是git clone+composer install
想让项目初始化后自动跑脚本?用 post-install-cmd 或 post-update-cmd 更实际
如果你的真实需求是:“新拉下代码、第一次 composer install 后就执行初始化逻辑(如生成 .env、清缓存、运行迁移)”,那应该用:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
-
post-install-cmd:每次执行composer install时触发(包括首次安装) -
post-update-cmd:每次composer update后触发
但要注意:它们会重复执行。如果脚本里有生成文件、写配置等操作,得自己加判断避免覆盖。例如:
"scripts": {
"post-install-cmd": [
"if [ ! -f .env ]; then cp .env.example .env; fi",
"php artisan key:generate"
]
}
性能影响很小,但兼容性上需留意:post-install-cmd 在 Composer 1.x 和 2.x 均有效;若用了 php 路径硬编码(如 /usr/bin/php),可能在不同环境失败,建议用 @php 别名。
post-create-project-cmd 真实使用场景和限制
它唯一有效的场景是:你正在维护一个可被 create-project 安装的模板包(比如 myorg/laravel-starter),并且希望用户执行:
composer create-project myorg/laravel-starter my-app
之后,自动完成初始化。这时,你必须在 myorg/laravel-starter 的 composer.json 里声明:
"scripts": {
"post-create-project-cmd": [
"@php -r \"copy('.env.example', '.env');\"",
"php artisan key:generate"
]
}
关键限制:
- 该脚本在用户机器上执行,所以不能依赖你的开发环境路径或扩展
- 如果用户用了
--no-scripts参数,这个钩子会被跳过 - Composer 2.2+ 开始,
post-create-project-cmd默认被禁用,需显式启用:composer config --global allow-plugins.composer/installers true(取决于插件策略)
最容易被忽略的一点:很多人以为 post-create-project-cmd 是“项目一建好就执行”,其实它执行时机是在 create-project 的最后阶段——也就是 vendor 已安装、autoload 已生成、但项目目录刚解压完的时候。如果你的脚本依赖尚未安装的第三方命令(比如 phpunit 或 laravel-zero),它会直接报错,因为此时 vendor/bin 还没被加入 PATH,也还没运行过 composer dump-autoload。

















