scripts字段必须位于composer.json顶层,与require同级;键名严格区分大小写和符号;值推荐用字符串数组;php回调需手动引入autoload.php;远程部署需显式ssh调用,不可依赖post-install-cmd自动触发。

scripts字段必须写在composer.json顶层,否则静默失效
很多人改完composer.json发现脚本不执行,根本原因是把scripts塞进了extra、config或autoload里。它必须和require、autoload同级,缩进错一级、多一个逗号、用了全角引号,Composer 都不报错,只当没看见。
键名严格区分大小写和符号:deploy:install只能用composer deploy:install调用,composer Deploy:install或composer deploy install完全无效。值推荐用字符串数组而非单个字符串,避免 shell 解析歧义:
"scripts": {
"deploy:install": [
"php artisan config:clear",
"php artisan cache:clear",
"php artisan view:cache"
]
}
- Windows 用户注意:
ci:lint这类含冒号的命令,CMD 下必须加双引号:composer run-script "ci:lint" - 别在
scripts里写绝对路径或硬编码环境判断,改用php -r "echo getenv('APP_ENV') ?: 'prod';"动态读取 - 如果脚本依赖
phpunit等 dev 工具,但部署时用了--no-dev,脚本会直接报sh: phpunit: not found——应拆出独立命令,显式调用composer run-script xxx --no-dev
PHP回调脚本必须手动require autoload.php
写"health:check": "App\Scripts\HealthCheck::run"后报Class not found?不是 Composer bug,是设计行为:它默认不加载vendor/autoload.php,防止脚本污染主流程上下文。
第一行必须显式引入,且路径要对:
// scripts/health-check.php
require __DIR__ . '/../vendor/autoload.php';
class HealthCheck {
public static function run($composer, $io) {
if (!class_exists('Illuminate\Foundation\Application')) {
die('Laravel not loaded');
}
// 实际逻辑
}
}
-
__DIR__指向当前脚本所在目录,若脚本在scripts/下,就不能写include 'vendor/autoload.php' - 加判断快速定位问题:
if (!class_exists('Composer\Autoload\ClassLoader')) { die('autoload not loaded'); } - 回调方法必须是
public static,类需已配置在autoload或autoload-dev中
远程部署不能靠post-install-cmd自动触发
很多人以为git push后线上服务器会自动跑post-install-cmd,其实它只在你当前执行composer install的那台机器上运行。CI 构建机上跑完composer install --no-dev,脚本只在构建机执行,和目标服务器无关。
真正可用的模式是分阶段显式调用:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 本地准备:
composer install --no-dev --optimize-autoloader --classmap-authoritative - 推代码:
rsync -avz --exclude="vendor/" --exclude=".git" --exclude="node_modules/" ./ user@prod:/var/www/app/ - 远程执行:
ssh user@prod 'cd /var/www/app && composer run-script deploy:install --no-dev --no-interaction' - 敏感操作如
php artisan migrate必须加--force和--no-interaction,否则卡在Are you sure?提示
所有远程命令都依赖 SSH 免密登录,否则阻塞在密码提示;vendor/绝不能随 rsync 同步——体积大、易中断、类加载路径错乱,应在目标机原地执行composer install。
参数传递必须用--分隔,否则脚本收不到
想传--filter=testLogin给 PHPUnit,却始终拿不到?因为 Composer 不解析参数,只负责透传,漏掉--分隔符,参数就被它自己吃掉了。
正确调用方式:
composer test:unit -- --filter=testLogin --group=fast
PHP 脚本中优先读$_SERVER['COMPOSER_ARGS'](Composer 4.0+ 提供),比$argv更可靠:
$args = $_SERVER['COMPOSER_ARGS'] ?? []; $filter = array_filter($args, fn($a) => str_starts_with($a, '--filter=')) ?: [];
- Shell 命令里慎用
$1、$2:Windows CMD 不支持,跨平台应封装成 PHP 入口处理 - 环境变量别依赖
$_ENV(CLI 下为空),统一用getenv('APP_ENV') - 脚本返回非零退出码(如
exit(1))时,composer run-script会报错并停止后续操作,适合做校验环节
实际部署中最容易被忽略的点是权限和用户上下文:Web 服务器用户(如www-data)没权限写storage/,导致php artisan config:cache失败;rsync --delete若源目录临时缺失文件,目标会被清空;而post-autoload-dump比post-install-cmd更可靠——它在 autoloader 生成后才执行,时机更精准。










