#!/bin/bash # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' PROJECT_ROOT="/www/wwwroot/chat.ay.lc" # <--- 确认这里的路径是否正确 export COMPOSER_ALLOW_SUPERUSER=1 echo -e "${BLUE}========================================${NC}" echo -e "${BLUE} 🚀 Laravel 稳健更新脚本 (带严格检查) ${NC}" echo -e "${BLUE}========================================${NC}" cd "$PROJECT_ROOT" || { echo -e "${RED}❌ 无法进入项目目录:$PROJECT_ROOT${NC}"; exit 1; } # 1. Git Pull(先重置 lock 文件,避免服务器环境差异导致冲突) echo -e "${YELLOW}[1/7] 拉取代码...${NC}" git checkout -- composer.lock package-lock.json 2>/dev/null || true git fetch origin && git pull origin master if [ $? -ne 0 ]; then echo -e "${RED}❌ Git 失败${NC}"; exit 1; fi # 2. Composer Install (关键检查点) echo -e "${YELLOW}[2/7] 安装依赖 (Composer)...${NC}" composer install --no-dev --optimize-autoloader --classmap-authoritative --no-interaction COMPOSER_EXIT_CODE=$? if [ $COMPOSER_EXIT_CODE -ne 0 ]; then echo -e "${RED}========================================${NC}" echo -e "${RED} ❌ 致命错误:Composer 安装失败! ${NC}" echo -e "${RED} vendor/autoload.php 未生成,网站将不可用。 ${NC}" echo -e "${RED} 请检查上方的错误日志 (网络?内存?PHP版本?) ${NC}" echo -e "${RED}========================================${NC}" exit 1 fi # 检查文件是否真的存在 if [ ! -f "vendor/autoload.php" ]; then echo -e "${RED}❌ 奇怪:Composer 显示成功,但 vendor/autoload.php 不存在!${NC}" exit 1 fi echo -e "${GREEN}✅ 依赖安装成功且文件存在。${NC}" # 关键 Composer polyfill 文件检查:若 vendor 目录不完整,Laravel 接口会返回 PHP Warning HTML,前端会误判为 JSON 解析失败 if [ ! -f "vendor/symfony/polyfill-mbstring/bootstrap.php" ]; then echo -e "${RED}========================================${NC}" echo -e "${RED} ❌ 致命错误:Composer vendor 不完整! ${NC}" echo -e "${RED} 缺少 vendor/symfony/polyfill-mbstring/bootstrap.php。 ${NC}" echo -e "${RED} 请删除线上 vendor 后重新执行 composer install。 ${NC}" echo -e "${RED}========================================${NC}" exit 1 fi # 重新生成生产环境 autoload,避免 autoload_files.php 指向已缺失的旧文件 composer dump-autoload --no-dev --optimize --classmap-authoritative --no-interaction if [ $? -ne 0 ]; then echo -e "${RED}❌ Composer autoload 重建失败${NC}"; exit 1; fi # 用当前 PHP 直接加载 Laravel autoload,提前暴露 vendor 缺文件 / 权限 / autoload 缓存问题 php -d opcache.enable_cli=0 -r "require __DIR__.'/vendor/autoload.php'; echo 'Composer autoload OK'.PHP_EOL;" if [ $? -ne 0 ]; then echo -e "${RED}========================================${NC}" echo -e "${RED} ❌ 致命错误:PHP 无法加载 vendor/autoload.php! ${NC}" echo -e "${RED} 请检查 vendor 是否完整、文件权限是否正确、Composer 是否使用了正确 PHP 版本。 ${NC}" echo -e "${RED}========================================${NC}" exit 1 fi # 3. 前端构建 echo -e "${YELLOW}[3/7] 前端构建 (npm run build)...${NC}" npm run build if [ $? -ne 0 ]; then echo -e "${RED}❌ npm run build 失败${NC}"; exit 1; fi echo -e "${GREEN}✅ 前端资源构建完成。${NC}" # 4. 数据库迁移 echo -e "${YELLOW}[5/7] 数据库迁移...${NC}" php artisan migrate --force # 5. 优化 echo -e "${YELLOW}[5/8] 生产环境优化...${NC}" # 注意:optimize 命令内部已经包含了 config:cache, route:cache, event:cache,此处无须多余处理 php artisan optimize:clear && php artisan optimize && php artisan view:cache # 6. 重启 Horizon / 队列进程 echo -e "${YELLOW}[6/8] 重启 Horizon...${NC}" php artisan horizon:terminate # 7. 重载 PHP-FPM / opcache,避免 Web 进程继续使用旧的 autoload 缓存 echo -e "${YELLOW}[7/8] 重载 PHP-FPM...${NC}" PHP_FPM_RELOADED=0 if command -v systemctl >/dev/null 2>&1; then for svc in php-fpm php-fpm-84 php-fpm-83 php-fpm-82 php84-php-fpm php83-php-fpm php82-php-fpm; do if systemctl list-unit-files "$svc.service" >/dev/null 2>&1; then systemctl reload "$svc" >/dev/null 2>&1 || systemctl restart "$svc" >/dev/null 2>&1 || true PHP_FPM_RELOADED=1 fi done fi for init_script in /etc/init.d/php-fpm /etc/init.d/php-fpm-*; do if [ -x "$init_script" ]; then "$init_script" reload >/dev/null 2>&1 || "$init_script" restart >/dev/null 2>&1 || true PHP_FPM_RELOADED=1 fi done if [ "$PHP_FPM_RELOADED" -eq 1 ]; then echo -e "${GREEN}✅ PHP-FPM 已尝试重载。${NC}" else echo -e "${YELLOW}⚠️ 未识别到 PHP-FPM 服务,请在面板中手动重启当前站点使用的 PHP。${NC}" fi # 6. 权限 (针对宝塔或Nginx+FPM环境的修正) echo -e "${YELLOW}[8/8] 修复权限...${NC}" # 将所有文件所属权变更为 Web 运行用户(如 www),防止 root 权限导致框架日志或缓存写入失败 chown -R www:www . # 默认读写执行权限 chmod -R 755 . # 针对 Laravel 必须具备写入权限的核心目录给予 775 权限 chmod -R 775 storage bootstrap/cache echo -e "${GREEN}========================================${NC}" echo -e "${GREEN} 🎉 更新成功!网站已恢复。 ${NC}" echo -e "${GREEN}========================================${NC}"