离线环境配Composer脚本核心是杜绝联网行为,应改用post-autoload-dump事件,执行COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader && composer dump-autoload -o && composer run-script post-autoload-dump,并确保脚本使用绝对路径、显式判断和escapeshellarg防护。

离线环境里配 Composer 自动化脚本,核心不是“能不能跑”,而是“会不会联网”——post-install-cmd 之类钩子默认会触发插件、加载远程仓库配置、甚至调用 composer config --list 查全局设置,这些行为在断网时全会失败。必须从事件选择、命令写法、执行方式三方面做硬隔离。
为什么 post-install-cmd 在离线机上静默失效?
它本身不联网,但常见错误写法会让它间接触发网络行为:
- 命令里写了
composer dump-autoload—— 这个命令会读composer.json里的repositories配置,哪怕设了COMPOSER_DISABLE_NETWORK=1,只要"repositories": [{"type": "packagist", "url": false}]存在,就会直接报错退出 - 用了
@php artisan xxx却没确认artisan文件是否已存在、是否可执行(离线部署常漏拷) - 脚本里调用了第三方包的 CLI 命令(如
phpstan),而该包未提前装进vendor/或没加--no-dev过滤 -
post-install-cmd只在composer.lock不存在或过期时触发,离线部署通常 lock 已存在,它根本不会跑
离线可用的脚本事件选哪个?
别赌 post-install-cmd,改用 post-autoload-dump —— 它触发时机更确定(每次 composer install 或 dump-autoload 都会执行),且不依赖锁文件状态,更重要的是:它只在 autoloader 生成后运行,此时 vendor/autoload.php 已就位,PHP 类能正常加载。
实操建议:
- 把关键逻辑(如清缓存、生成配置)全挪到
post-autoload-dump - 避免在脚本里再调
composer命令,只用 PHP 或 shell 基础命令(rm,cp,echo) - 如果必须调用
artisan,先加判断:if [ -f artisan ]; then php artisan config:clear; fi
离线执行脚本的命令怎么写才稳?
不能只靠 composer install 自动触发,得拆成两步:先确保 autoload 生效,再手动跑脚本。这是离线部署最可控的组合:
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader && composer dump-autoload -o && composer run-script post-autoload-dump
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
说明:
-
--no-autoloader是为了跳过默认 autoload 生成(它可能因路径问题失败),后面用dump-autoload -o显式重建 -
composer run-script post-autoload-dump是显式调用,不依赖事件自动触发,可控性强 - 所有脚本命令必须是“无副作用”的:不查网络、不读远程 repo、不依赖未打包进 vendor 的 dev 工具
脚本里怎么安全读取环境变量和路径?
离线机上 getenv('APP_ENV') 可能为空,__DIR__ 相对路径也可能因工作目录变化出错。必须用绝对路径 + 显式判断:
示例(放在 scripts/deploy.php 中):
#!/usr/bin/env php
<?php
$root = __DIR__ . '/..';
if (!is_file($root . '/vendor/autoload.php')) {
exit("❌ vendor/autoload.php not found\n");
}
require_once $root . '/vendor/autoload.php';
$env = $_SERVER['APP_ENV'] ?? 'prod';
if ($env !== 'prod') {
exit("⚠️ Not in production env, skipped.\n");
}
// 安全清理缓存
$cacheDir = $root . '/storage/framework/cache/data';
if (is_dir($cacheDir)) {
system("rm -rf " . escapeshellarg($cacheDir));
echo "✅ Cleared cache\n";
}
然后在 composer.json 里配:"post-autoload-dump": ["php scripts/deploy.php"]
注意:escapeshellarg() 必须加,防止路径含空格或特殊字符导致 rm -rf 误删。
最容易被忽略的一点:脚本文件本身要随项目一起打包进离线环境,不能只靠 composer install 下载——它不是包依赖,是部署资产。

















