composer脚本需用独立php文件(如scripts/validate-config.php)封装校验逻辑,通过pre-install-cmd/pre-update-cmd钩子调用,失败时输出错误到stderr并exit(1),确保路径、权限、环境变量在本地与ci中一致。

Composer 脚本里不能直接写校验逻辑,得靠外部命令或 PHP 文件
Composer 的 scripts 字段本质只是命令行调用入口,不支持内联 PHP 或条件判断。想在校验失败时中断安装/更新流程,必须把逻辑抽到独立可执行单元里——要么是 shell 脚本,要么是 PHP 文件(推荐)。
常见错误是试图在 composer.json 里写类似 "php -r \"if (!file_exists('config.php')) die('missing');\"" 这种命令:它虽能运行,但可读性差、调试难、错误信息不友好,且 Windows 下容易因引号解析失败而静默跳过。
- 校验逻辑应封装在
scripts/validate-config.php这类明确路径的文件中 - 该文件需有可执行权限(Linux/macOS),且首行加
#!/usr/bin/env php - 必须以非零退出码(如
exit(1))表示校验失败,否则 Composer 会认为脚本成功并继续执行后续步骤
怎么在 composer.json 中正确注册校验脚本
关键不是“怎么写”,而是“怎么挂载”——要利用 Composer 的事件钩子,而不是手动运行。最常用的是 pre-install-cmd 和 pre-update-cmd,它们会在依赖安装或更新前触发:
{
"scripts": {
"validate-config": "php scripts/validate-config.php",
"pre-install-cmd": ["@validate-config"],
"pre-update-cmd": ["@validate-config"]
}
}
注意两点:一是用 @validate-config 引用内部脚本名,避免硬编码路径;二是多个钩子共用同一逻辑时,别重复写命令,用引用方式更易维护。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 不要在
post-*钩子里做校验——那时依赖已装完,出错也晚了 - 如果校验耗时较长(比如要连数据库),考虑加
--no-scripts参数临时跳过,避免 CI 流水线卡住 - Composer v2.2+ 支持
script-execution-mode配置,但默认就是按顺序执行,无需额外设置
validate-config.php 里怎么写可维护的校验逻辑
核心原则:失败时输出清晰错误信息 + 用 exit(1) 终止,成功则默默退出(exit(0) 可省略)。别用 die() 或 echo 后不退出,那会导致 Composer 认为脚本成功。
<?php // scripts/validate-config.php
if (!file_exists('config/database.php')) {
fwrite(STDERR, "ERROR: config/database.php is missing.\n");
exit(1);
}
$config = require 'config/database.php';
if (empty($config['host'])) {
fwrite(STDERR, "ERROR: database.host is empty in config/database.php.\n");
exit(1);
}
- 始终用
STDERR输出错误,避免和正常日志混在一起 - 校验顺序建议从文件存在性 → 格式合法性 → 业务约束,逐层递进
- 避免在脚本里加载 Laravel/ Symfony 等全栈框架——启动开销大,纯 PHP 原生判断足够
为什么本地跑通了,CI 上却失败?
最常见的坑是路径和工作目录不一致。Composer 执行脚本时,当前工作目录是项目根目录(即 composer.json 所在处),但某些 CI 环境(如 GitLab Runner 的 docker executor)可能以非 root 用户运行,导致 scripts/ 目录不可读,或 config/ 文件被 .gitignore 排除后根本不存在。
- CI 中务必确认
scripts/validate-config.php已提交到仓库,且权限为644(无需755,Composer 会通过php解释器执行) - 用
composer run-script validate-config --verbose在 CI 前本地模拟,观察完整输出和退出码 - 如果校验依赖环境变量(如
APP_ENV),别假设它们一定存在——CI 需显式注入,或在脚本里设默认值再校验
校验脚本真正的复杂点不在语法,而在它必须同时适应开发者本地环境、CI 构建环境、以及不同部署目标的约束差异。路径、权限、环境变量、文件是否被忽略——这些看似外围的问题,往往比校验逻辑本身更容易让整个流程静默失效。










