PHP 怎么PHP 边缘缓存

wen PHP项目 1

本文目录导读:

PHP 怎么PHP 边缘缓存

  1. 配合 CDN 做边缘缓存
  2. 与 Nginx 反向代理结合(FastCGI Cache)
  3. PHP 应用层边缘缓存(静态化 + 预热)
  4. 使用 Varnish 作为专用缓存层
  5. 边缘缓存的最佳实践总结
  6. 关键注意点

在 PHP 中实现“边缘缓存”,通常指的是利用 CDN反向代理(如 Nginx、Varnish)应用层缓存 将内容缓存在离用户更近的节点上,从而加速页面加载并减轻源服务器压力。

以下是几种在 PHP 中配合边缘缓存的典型实现方式:


配合 CDN 做边缘缓存

这是最标准的“边缘缓存”,你需要在 PHP 中正确设置 HTTP 缓存头,让 CDN 节点知道何时缓存、缓存多久。

// 缓存1小时,允许CDN/浏览器缓存
$expires = 3600;
header("Cache-Control: public, max-age={$expires}");
header("Expires: " . gmdate('D, d M Y H:i:s', time() + $expires) . " GMT");
// 输出页面内容
echo "这是被缓存的内容...";

关键点:

  • Cache-Control: public 表示允许 CDN 和浏览器缓存。
  • max-age 指定缓存有效时间(秒),因用户而异(如登录态),需要设置 privateno-cache,或使用 Cookie 校验。

高级用法:基于缓存标签(Surrogate-Key)
某些 CDN(如 Fastly、Cloudflare)支持通过 HTTP 头标记缓存标签,方便批量清除:

header("Surrogate-Key: blog-post:123 category:news");
// 后续可通过CDN API 删除包含该标签的所有缓存

与 Nginx 反向代理结合(FastCGI Cache)

Nginx 作为反向代理,可以缓存 PHP 输出的静态化页面,PHP 无需修改代码,但可以通过控制响应头来决定是否缓存。

Nginx 配置示例:

proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=mycache:10m;
server {
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        # 启用缓存
        fastcgi_cache mycache;
        fastcgi_cache_valid 200 60m;    # 成功响应缓存60分钟
        fastcgi_cache_use_stale error timeout updating;
        # 根据PHP自定义头决定是否绕过缓存
        fastcgi_no_cache $skip_cache;
        fastcgi_cache_bypass $skip_cache;
    }
}

PHP 中动态控制:

// 如果用户已登录,禁止Nginx缓存
if ($logged_in) {
    header("X-Accel-Expires: 0");   // 立即过期Nginx缓存
    header("Cache-Control: no-cache, private");
} else {
    header("X-Accel-Expires: 3600"); // 强制Nginx缓存1小时
    header("Cache-Control: public, max-age=3600");
}

PHP 应用层边缘缓存(静态化 + 预热)

如果无法修改服务器配置,可以在 PHP 内部实现“伪边缘缓存”:将渲染好的 HTML 写入文件,再由 CDN 或 Nginx 作为静态文件提供。

示例:文件缓存 + 主动刷新

$cacheFile = __DIR__ . '/cache/page_' . md5($_SERVER['REQUEST_URI']) . '.html';
$cacheTime = 3600; // 1小时
// 检查缓存是否存在且未过期
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheTime)) {
    readfile($cacheFile);
    exit;
}
// 正常生成页面
ob_start();
echo "动态生成的内容...";
$content = ob_get_flush();
// 写入缓存文件
file_put_contents($cacheFile, $content);

适用于: 无CDN、低成本服务器,且内容变化不频繁的站点。


使用 Varnish 作为专用缓存层

Varnish 位于 PHP 与用户之间,专门处理 HTTP 缓存,PHP 通过设置 Cache-ControlSurrogate-Control 头控制 Varnish 行为。

PHP 示例(设置 TTL 和缓存分组):

header("Cache-Control: public, max-age=600, s-maxage=300");
// s-maxage 是共享缓存(如Varnish/CDN)专用的最大存活时间
header("Surrogate-Control: content=\"text/html\", max-age=3600");

Varnish VCL 可据此决定缓存策略:

sub vcl_recv {
    if (req.http.Authorization || req.http.Cookie) {
        return (pass); // 带Cookie/认证的不缓存
    }
}
sub vcl_backend_response {
    if (beresp.http.Surrogate-Control) {
        # 可提取Surrogate-Control中的指令
    }
}

边缘缓存的最佳实践总结

场景 推荐方式 注意事项
静态页面(文章、首页) CDN + Cache-Control: public, max-age=3600 配合缓存标签快速失效
用户相关页面(购物车) 不缓存,或使用Cache-Control: private 或使用 ESI (Edge Side Includes) 部分缓存
频繁更新 Nginx FastCGI Cache + 主动刷新API 通过 X-Accel-Expires 头精细控制
离线完全静态化 PHP 文件缓存 + CDN 静态资源服务 需考虑缓存失效机制(如CMS的自动刷新)
使用专用缓存层 Varnish + Surrogate-Key 对于高流量站点性能极佳,但运维成本较高

关键注意点

  1. 避免缓存动态内容:登录态、购物车、CSRF Token 等页面必须设置 no-cacheprivate
  2. 缓存失效策略:建议使用 基于标签的失效(如 Surrogate-Key),而不要用 URL 模式清除(效率低)。
  3. 混合模式:可以用 ESI(Edge Side Includes)技术,将页面中动态部分(如用户昵称)单独请求,其余部分缓存,PHP 可通过 esi:include 占位符实现。
  4. 测试:使用 curl -I 查看响应头中的 Cache-ControlAgeX-Cache 确认缓存是否生效。

如果你能给出具体场景(如 WordPress 站点、API 接口、会员系统等),我可以提供更针对性的缓存方案。

抱歉,评论功能暂时关闭!