composer脚本是php项目中防止人为遗漏、统一环境行为的必要控制点,需用php类方法替代shell命令、将关键逻辑移至post-autoload-dump钩子、避免dev依赖干扰,并通过显式run-script调用保障生产环境执行。

Composer 脚本不是“能用就行”的可选项,而是 PHP 项目中防止人为遗漏、统一环境行为的必要控制点。它不替代 CI/CD,但能确保 composer install 在任意机器上执行后,项目至少具备可运行基础——比如缓存清空、配置生成、目录初始化这些事,不该靠文档提醒或新人记忆。
post-install-cmd 和 post-update-cmd 总是不触发?检查是否在生产环境被跳过
本地跑得好,部署机上 post-install-cmd 完全静默?大概率是用了 --no-dev(生产部署标准操作),而你的脚本写在了 require-dev 依赖里,或脚本本身调用了 phpunit 这类 dev-only 命令。
- Composer 默认只在
dev模式下执行 scripts(除非显式启用) - 部署时加
--no-dev会直接跳过所有 scripts —— 不报错,也不提示 - 正确做法:把真正要执行的命令拆成独立脚本名(如
deploy:post-install),再用composer run-script deploy:post-install --no-dev显式调用 - 避免在
post-install-cmd中调用phpunit或infection等仅存在于require-dev的命令
用 PHP 类方法代替 shell 命令,解决跨平台和错误不可见问题
写 "cp .env.example .env" 看似简单,但在 Windows 上会失败;写 "chmod -R 755 runtime/" 在 Docker 部署时可能因 UID 不匹配静默失效;更糟的是,shell 命令出错时 Composer 往往只显示 Script xxx handling xxx event returned with error code 1,根本看不出哪一行崩了。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 改用单入口 PHP 脚本:如
"post-install-cmd": "php build/init-project.php" - 脚本内可做权限判断、路径存在性检查、
file_exists()+copy()替代cp、is_writable()替代盲目chmod - PHP 脚本能用
try/catch捕获异常,输出具体错误行和上下文,调试成本直降 - 注意:脚本默认不加载项目 autoloader,需手动
require __DIR__.'/../vendor/autoload.php';
post-autoload-dump 是最可靠的钩子,比 post-install-cmd 更值得依赖
post-install-cmd 只在 composer install 且 lock 文件有变更时才触发;如果 lock 没变,重跑 install 就不会进这个钩子——但你写的缓存清理、代理类生成等逻辑,其实应该每次 autoloader 更新后都执行。
-
post-autoload-dump在每次composer dump-autoload后必走,包括install、update、甚至手动调用时 - 适合场景:生成注解代理类、扫描容器配置、刷新框架 classmap、预热 DI 容器
- PHP 回调中可通过
$event->getComposer()->getPackage()获取当前根包信息,读取extra字段配置(唯一推荐放自定义参数的位置) - 别在
post-autoload-dump里干耗时操作(如git clone或远程请求),它卡住会导致整个install流程阻塞
数据库迁移不能全交给 post-update-cmd,必须分环境控制
把 "post-update-cmd": "php artisan migrate" 直接写进 composer.json,上线时 composer update 会偷偷执行迁移,风险极高——没人审核 SQL、没备份、没回滚准备。
- 迁移应拆为显式命令:
"migrate:dev": "php artisan migrate --env=local"、"migrate:prod": "php artisan migrate --env=production --force" -
post-update-cmd只保留无害操作(如dump-autoload -o),迁移留给人工或 CI 步骤显式触发 - 若真要用自动迁移,务必通过环境变量控制:
"post-update-cmd": ["sh -c 'if [ \"$APP_ENV\" = \"local\" ]; then php artisan migrate; fi'"] - Phinx 用户注意:
vendor/bin/phinx migrate -e $PHINX_ENV中的$PHINX_ENV是 shell 变量,不是 PHP 的$_ENV,得确保部署环境已 export
最常被忽略的一点:脚本里读取的路径都是以项目根目录为基准,但 vendor/bin/xxx 这类命令在某些容器或 symlink 环境下可能找不到。与其拼路径,不如在 PHP 脚本里用 exec('which php') + __DIR__ 动态构造执行上下文——自动化不是写死,而是让每一步都可验证、可中断、可追溯。










