本文目录导读:

我来详细介绍 PHP 增量静态生成的几种实现方法:
基本原理
增量静态生成的核心思想:只重新生成发生变化的页面,而不是全站重新生成。
实现方案
基于文件时间戳
<?php
class IncrementalStaticGenerator {
private $cacheDir = 'cache/';
private $sourceDir = 'source/';
// 检查是否需要重新生成
public function needRegenerate($pageName) {
$sourceFile = $this->sourceDir . $pageName . '.php';
$cacheFile = $this->cacheDir . $pageName . '.html';
// 如果没有缓存文件,需要生成
if (!file_exists($cacheFile)) {
return true;
}
// 如果源文件更新,需要重新生成
if (filemtime($sourceFile) > filemtime($cacheFile)) {
return true;
}
return false;
}
// 生成静态页面
public function generate($pageName) {
if (!$this->needRegenerate($pageName)) {
return false;
}
ob_start();
include $this->sourceDir . $pageName . '.php';
$content = ob_get_clean();
file_put_contents(
$this->cacheDir . $pageName . '.html',
$content
);
return true;
}
}
更新
<?php
class ContentBasedGenerator {
private $db;
private $cacheDir = 'cache/';
private $contentTable = 'content_update_log';
// 记录内容变更
public function markContentChanged($contentId) {
$sql = "INSERT INTO {$this->contentTable}
(content_id, change_time)
VALUES (?, NOW())
ON DUPLICATE KEY UPDATE change_time = NOW()";
$stmt = $this->db->prepare($sql);
$stmt->execute([$contentId]);
}
// 获取需要更新的页面
public function getChangedPages() {
$sql = "SELECT DISTINCT p.page_id, p.page_name
FROM pages p
JOIN page_content pc ON p.page_id = pc.page_id
JOIN content_update_log l ON pc.content_id = l.content_id
WHERE l.change_time > p.last_generated_time";
return $this->db->query($sql)->fetchAll();
}
// 生成更新的页面
public function generateChangedPages() {
$pages = $this->getChangedPages();
foreach ($pages as $page) {
$this->generateSinglePage($page['page_id']);
$this->updateGeneratedTime($page['page_id']);
}
}
}
基于文件的增量生成
<?php
class FileBasedIncrementalGenerator {
private $templateDir = 'templates/';
private $outputDir = 'public/';
private $hashFile = 'cache/page_hashes.json';
// 检查文件内容是否变化
public function hasFileChanged($file) {
$hashes = $this->loadHashes();
$currentHash = md5_file($file);
if (!isset($hashes[$file]) || $hashes[$file] !== $currentHash) {
$hashes[$file] = $currentHash;
$this->saveHashes($hashes);
return true;
}
return false;
}
// 增量生成
public function incrementalGenerate() {
$files = glob($this->templateDir . '*.php');
foreach ($files as $file) {
if ($this->hasFileChanged($file)) {
$outputFile = $this->outputDir .
basename($file, '.php') . '.html';
ob_start();
include $file;
$content = ob_get_clean();
file_put_contents($outputFile, $content);
echo "Regenerated: " . basename($outputFile) . PHP_EOL;
}
}
}
private function loadHashes() {
if (file_exists($this->hashFile)) {
return json_decode(file_get_contents($this->hashFile), true);
}
return [];
}
private function saveHashes($hashes) {
file_put_contents($this->hashFile, json_encode($hashes));
}
}
数据库驱动的增量生成
<?php
class DBDrivenIncrementalGenerator {
private $pdo;
private $outputDir = 'public/';
// 获取需要更新的内容ID
public function getContentUpdates() {
$sql = "SELECT c.*, t.template_file
FROM contents c
JOIN content_templates t ON c.template_id = t.template_id
WHERE c.is_published = 1
AND (c.updated_at > c.last_generated_at
OR c.last_generated_at IS NULL)";
return $this->pdo->query($sql)->fetchAll();
}
// 生成特定内容
public function generateContent($content) {
$template = file_get_contents($content['template_file']);
// 替换内容变量
$html = $this->replaceVariables($template, $content);
// 生成文件名
$filename = $this->generateFilename($content);
$filepath = $this->outputDir . '/' . $filename;
// 保存文件
file_put_contents($filepath, $html);
// 更新生成时间
$this->updateGeneratedTime($content['id']);
return $filename;
}
// 批量增量更新
public function batchIncrementalUpdate() {
$contents = $this->getContentUpdates();
$generated = [];
foreach ($contents as $content) {
$filename = $this->generateContent($content);
$generated[] = $filename;
// 更新相关页面(如列表页、首页等)
$this->updateRelatedPages($content);
}
return $generated;
}
private function updateRelatedPages($content) {
// 更新包含此内容的列表页、首页等
if ($content['is_featured']) {
$this->generateHomepage();
}
$this->generateCategoryList($content['category_id']);
}
}
完整的增量静态生成系统
<?php
class FullStaticGenerationSystem {
private $config;
private $db;
private $logger;
private $cache;
public function __construct() {
$this->config = require 'config.php';
$this->db = new PDO(/* 数据库连接 */);
$this->logger = new Logger();
$this->cache = new Cache();
}
// 主生成方法
public function generate($pageType, $pageId = null) {
switch ($pageType) {
case 'single':
return $this->generateSingle($pageId);
case 'list':
return $this->generateList($pageId);
case 'home':
return $this->generateHome();
case 'all':
return $this->generateAll();
}
}
// 生成单页
private function generateSingle($id) {
// 检查是否需要更新
if (!$this->needsUpdate($id, 'single')) {
return ['status' => 'skipped', 'id' => $id];
}
// 获取数据
$data = $this->getPageData($id);
// 渲染模板
$html = $this->renderTemplate('single', $data);
// 保存文件
$filename = $this->saveToFile($data['slug'], $html);
// 更新标记
$this->markGenerated($id, 'single');
return ['status' => 'generated', 'file' => $filename];
}
// 检查是否需要更新
private function needsUpdate($id, $type) {
// 检查内容是否更新
$lastModified = $this->getLastModified($id, $type);
$lastGenerated = $this->getLastGenerated($id, $type);
return $lastModified > $lastGenerated;
}
// 智能批量生成
public function smartBatchGenerate() {
// 获取所有需要更新的内容
$updates = $this->getQueue();
$results = [];
foreach ($updates as $update) {
// 更新单个页面
$result = $this->generate($update['type'], $update['id']);
$results[] = $result;
// 更新相关列表页
if ($update['type'] === 'single') {
$this->updateListsContaining($update['id']);
}
}
// 更新站点地图
$this->updateSitemap();
return $results;
}
// 热更新:在线替换文件
public function hotUpdate($file) {
$tempFile = $file . '.tmp';
$backupFile = $file . '.bak';
// 生成新版本到临时文件
$this->generateToFile($file, $tempFile);
// 备份原文件
copy($file, $backupFile);
// 原子替换
rename($tempFile, $file);
// 清理备份
unlink($backupFile);
}
}
使用建议
触发更新时机:发布/更新时**:立即触发相关页面更新
- 定时任务:设置cron job定期检查更新
- Webhook:通过API回调触发更新
Cron Job 示例:
# 每小时执行增量更新 0 * * * * /usr/bin/php /path/to/generator.php --incremental # 每天凌晨全量更新 0 3 * * * /usr/bin/php /path/to/generator.php --full
监控和日志:
// 添加日志记录
class GenerationLogger {
public function logGeneration($file, $status) {
$log = sprintf(
"[%s] %s - %s\n",
date('Y-m-d H:i:s'),
$file,
$status
);
file_put_contents('generation.log', $log, FILE_APPEND);
}
}
注意事项
- 文件锁定:并发访问时使用
flock()防止冲突 - 权限管理:确保缓存目录可写
- 备份机制:更新失败时能回滚
- 监控告警:生成失败时及时通知
- 性能优化:使用内存缓存减少数据库查询
这种增量静态生成方案可以有效减少服务器负载,提高页面响应速度,特别适合内容更新频繁的网站。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播