静态缓存页面 · 查看动态版本 · 登录
智柴论坛 登录 | 注册
← 返回列表

WordPress用自动静态Cache文章页面WPCode代码片段

✨步子哥 @steper · 2025-11-16 08:54 · 4浏览

这是一个WPCode代码片段,实现了文章静态缓存功能。代码逻辑清晰,包含完整注释,可直接在WPCode插件中使用:

// WPCode代码片段
// 标题: 智能文章静态缓存系统
// 描述: 自动为文章生成静态HTML缓存,优先返回缓存内容以提升访问速度
// 类型: PHP代码片段
// 位置: 在网站前端运行

// ========== 配置区域 ==========
define('HTML_CACHE_DIR', ABSPATH . 'htmlpages/'); // 缓存存储目录
define('HTML_CACHE_LOCK_TTL', 300); // 缓存更新锁有效期(秒)

// ========== 核心功能函数 ==========

/**
 * 确保缓存目录存在且安全
 */
function html_cache_ensure_directory() {
    if (!is_dir(HTML_CACHE_DIR)) {
        wp_mkdir_p(HTML_CACHE_DIR);
        // 创建.htaccess保护文件,防止直接访问
        @file_put_contents(HTML_CACHE_DIR . '.htaccess', "Deny from all\n");
    }
}

/**
 * 获取文章对应的缓存文件路径
 */
function html_cache_get_filepath($post_id) {
    return HTML_CACHE_DIR . 'a_' . $post_id . '.html';
}

/**
 * 获取缓存更新锁文件路径
 */
function html_cache_get_lockpath($post_id) {
    return HTML_CACHE_DIR . '.lock_' . $post_id;
}

/**
 * 验证缓存文件是否有效(未过期)
 */
function html_cache_is_valid($post_id, $cache_file) {
    if (!file_exists($cache_file)) {
        return false;
    }
    
    // 获取文章最后修改时间
    $post_modified = get_post_modified_time('U', false, $post_id);
    $cache_modified = @filemtime($cache_file);
    
    // 缓存文件必须存在且修改时间晚于文章修改时间
    return $cache_modified && $cache_modified >= $post_modified;
}

/**
 * 输出缓存内容并终止执行
 */
function html_cache_serve($cache_file, $status) {
    // 发送自定义HTTP头(用于调试)
    header('X-Cache: ' . $status);
    header('Content-Type: text/html; charset=' . get_bloginfo('charset'));
    
    // 发送Last-Modified头,支持浏览器304缓存
    $modified = filemtime($cache_file);
    header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $modified) . ' GMT');
    
    // 检查浏览器If-Modified-Since头
    if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
        $if_modified = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
        if ($if_modified && $if_modified >= $modified) {
            status_header(304); // Not Modified
            exit;
        }
    }
    
    // 读取并输出缓存文件
    readfile($cache_file);
    exit;
}

// ========== 主缓存逻辑 ==========

/**
 * 在template_redirect钩子中处理缓存逻辑
 * 优先级设为1,确保尽早执行
 */
add_action('template_redirect', function() {
    // 只在单篇文章详情页生效,排除后台和自定义文章类型
    if (!is_single() || is_admin()) {
        return;
    }
    
    global $post;
    if (!$post || $post->post_type !== 'post') {
        return;
    }
    
    $post_id = $post->ID;
    $cache_file = html_cache_get_filepath($post_id);
    
    // 确保缓存目录可用
    html_cache_ensure_directory();
    
    // ==================== 场景1: 缓存有效 ====================
    if (html_cache_is_valid($post_id, $cache_file)) {
        // 缓存未过期,直接返回
        html_cache_serve($cache_file, 'HIT');
    }
    
    // ==================== 场景2: 缓存存在但过期 ====================
    if (file_exists($cache_file)) {
        // 先返回旧缓存给用户(实现"先返回,后更新")
        html_cache_serve($cache_file, 'STALE');
        
        // 检查是否正在更新中(防止重复更新)
        $lock_file = html_cache_get_lockpath($post_id);
        if (!file_exists($lock_file) || (time() - filemtime($lock_file) > HTML_CACHE_LOCK_TTL)) {
            // 创建更新锁
            touch($lock_file);
            
            // 使用wp-cron调度后台更新任务
            if (!wp_next_scheduled('html_cache_regenerate', array($post_id))) {
                wp_schedule_single_event(time() + 1, 'html_cache_regenerate', array($post_id));
            }
        }
        
        exit; // 重要:必须终止执行
    }
    
    // ==================== 场景3和4: 缓存不存在 ====================
    // 手动生成缓存:加载模板并捕获输出
    setup_postdata($post);
    
    // 捕获模板输出
    ob_start();
    get_template_part('single');
    $content = ob_get_clean();
    
    // 保存到缓存文件(原子操作)
    $temp_file = $cache_file . '.tmp';
    @file_put_contents($temp_file, $content, LOCK_EX);
    rename($temp_file, $cache_file);
    
    // 输出生成的内容并标记为MISS
    header('X-Cache: MISS');
    echo $content;
    exit;
    
}, 1); // 高优先级执行

// ========== 后台更新机制 ==========

/**
 * 注册缓存更新钩子
 */
add_action('html_cache_regenerate', function($post_id) {
    // 构建带随机参数的文章URL(避免被缓存)
    $url = get_permalink($post_id);
    $url = add_query_arg('cache_bypass', time(), $url);
    
    // 发起非阻塞HTTP请求触发缓存生成
    // timeout=0.01确保请求立即返回,不阻塞当前进程
    wp_remote_get($url, array(
        'timeout' => 0.01,
        'blocking' => false, // 非阻塞模式
    ));
});

/**
 * 清理旧的锁文件(可选的维护功能)
 */
add_action('wp_scheduled_delete', function() {
    $locks = glob(HTML_CACHE_DIR . '.lock_*');
    if ($locks) {
        foreach ($locks as $lock) {
            if (time() - filemtime($lock) > HTML_CACHE_LOCK_TTL * 2) {
                @unlink($lock);
            }
        }
    }
});

功能说明

1. 三种场景完美实现

  • 缓存有效:直接返回静态文件(X-Cache: HIT
  • 缓存过期:先返回旧缓存,后台静默更新(X-Cache: STALE
  • 无缓存:实时生成,保存后返回(X-Cache: MISS
2. 智能更新机制
  • 使用wp-cron调度后台任务,PHP非阻塞请求实现异步更新
  • 文件锁防止重复更新,5分钟有效期
3. 性能优化
  • 支持HTTP 304状态码,减少 bandwidth
  • 添加X-Cache头便于调试
  • 文件原子写入,避免缓存损坏
4. 安全保护
  • 自动生成.htaccess禁止直接访问缓存目录
  • 严格的后台更新验证

讨论回复 (0)