$path, 'sha' => $item['sha'], 'size' => $item['size'] ?? 0]; } } $log .= "获取到 " . count($websiteFiles) . " 个远程文件\n"; $updated = 0; $created = 0; $errors = 0; $shaCacheFile = CACHE_DIR . '/file_shas.json'; $localShas = file_exists($shaCacheFile) ? json_decode(@file_get_contents($shaCacheFile), true) : []; if (!is_array($localShas)) $localShas = []; foreach ($websiteFiles as $file) { $relativePath = substr($file['path'], strlen('website/')); $localPath = __DIR__ . '/' . $relativePath; $remoteSha = $file['sha']; $dir = dirname($localPath); if (!is_dir($dir)) @mkdir($dir, 0755, true); $needsUpdate = false; $reason = ''; if (!file_exists($localPath)) { $needsUpdate = true; $reason = '文件缺失'; } else { $localSha = $localShas[$relativePath] ?? ''; if ($localSha !== $remoteSha) { $needsUpdate = true; $reason = '内容已变更'; } } if ($needsUpdate) { $contentUrl = sprintf('%s/%s/%s/contents/%s?ref=%s', GITEE_API_BASE, GITEE_OWNER, GITEE_REPO, $file['path'], GITEE_BRANCH); $contentData = httpGetJson($contentUrl); if ($contentData && isset($contentData['content'])) { $content = base64_decode(str_replace(["\n", "\r"], '', $contentData['content'])); if (@file_put_contents($localPath, $content) !== false) { $localShas[$relativePath] = $remoteSha; if ($reason === '文件缺失') { $created++; $log .= "✅ 创建: $relativePath\n"; } else { $updated++; $log .= "🔄 更新: $relativePath ($reason)\n"; } } else { $errors++; $log .= "❌ 写入失败: $relativePath\n"; } } else { $errors++; $log .= "❌ 获取内容失败: $relativePath\n"; } } } @file_put_contents($shaCacheFile, json_encode($localShas)); @file_put_contents(CACHE_DIR . '/update_check.json', json_encode([ 'timestamp' => time(), 'files' => count($websiteFiles), 'updated' => $updated, 'created' => $created, 'errors' => $errors ], JSON_PRETTY_PRINT)); $log .= "完成: 更新 $updated 个,创建 $created 个,错误 $errors 个\n"; $log .= "下次检查: " . date('Y-m-d H:i:s', time() + UPDATE_INTERVAL) . "\n\n"; @file_put_contents($logFile, $log, FILE_APPEND); } catch (Exception $e) { $log .= "异常: " . $e->getMessage() . "\n"; @file_put_contents($logFile, $log, FILE_APPEND); } } function httpGetJson($url) { $context = stream_context_create(['http' => ['method' => 'GET', 'header' => ['User-Agent: OSS-AutoUpdate/1.0', 'Accept: application/json'], 'timeout' => 30], 'ssl' => ['verify_peer' => true, 'verify_peer_name' => true]]); $response = @file_get_contents($url, false, $context); if ($response === false) return null; return json_decode($response, true); } register_shutdown_function('autoUpdateWebsite');