不依赖 ngx_cache_purge:使用 PHP 实现 Nginx 反代缓存刷新

作者:WenM

更新于:2026年4月30日 16:11

不依赖 ngx_cache_purge:使用 PHP 实现 Nginx 反代缓存刷新

在为 WordPress 或高性能网站部署 Nginx 反向代理缓存 时,很多站长都会遇到一个经典问题:

👉 缓存生成正常,但无法正确刷新缓存。

常见原因包括:

  • ngx_cache_purge 模块未正确编译
  • 使用发行版 Nginx(无法自行编译模块)
  • PURGE 请求始终返回 404 / 405
  • CDN + 反代双缓存导致刷新失效

如果你正被这个问题困扰,那么本文介绍的方案,可能是目前 兼容性最高、最稳定 的解决方法。


一、核心思路

传统方案:

PURGE /url
↓
ngx_cache_purge
↓
删除缓存

问题在于:

ngx_cache_purge 属于第三方模块。

它依赖:

  • 正确编译
  • 参数一致
  • 缓存 key 完全匹配

只要任何一步出现偏差,就会刷新失败。


新方案思路

我们换一个角度:

既然 Nginx 缓存本质是文件

那为什么不:

直接删除缓存文件?

于是方案变为:

PURGE 请求
↓
rewrite 转发
↓
PHP 接口
↓
计算缓存路径
↓
删除缓存文件

✔ 不依赖模块
✔ 不需要重新编译 Nginx
✔ 所有发行版可用
✔ 成功率极高


二、前提条件

本方案仅需要:

  • Nginx 反代服务器
  • 支持 PHP(FastCGI)
  • 已启用 proxy_cache

⚠️ 注意:仅反代服务器需要 PHP,源站无需修改。


三、第一步:Nginx 添加 rewrite 规则

在站点配置中加入:

rewrite ^/php-purge(/.*)$ /purge.php?path=$1 break;

作用说明

当你访问:

PURGE /php-purge/article/test/

Nginx 会内部改写为:

/purge.php?path=/article/test/

也就是说:

👉 所有缓存清理请求交给 PHP 处理。


四、第二步:创建 purge.php

在站点根目录创建:

purge.php

写入以下代码(站长帮 WenM 提供方案):

<?php
/**
 * 作者:站长帮(WenM)
 * Nginx 缓存清理接口
 * 调用方式: PURGE /php-purge/URL路径
 */

header('Content-Type: application/json; charset=utf-8');

$cache_root = '缓存目录'; //必须与反代配置中 proxy_cache_path 的路径一致
$domain = '反代站点域名'; //反代配置中对应配置 proxy_cache_key $host$uri$is_args$args;
$levels = [1, 2];

$path = $_GET['path'] ?? '';
if (empty($path)) {
    http_response_code(400);
    echo json_encode(['success'=>false,'error'=>'缺少 path 参数'],JSON_UNESCAPED_UNICODE);
    exit;
}

if (strpos($path,'..')!==false || strpos($path,'//')!==false) {
    http_response_code(400);
    echo json_encode(['success'=>false,'error'=>'非法路径'],JSON_UNESCAPED_UNICODE);
    exit;
}

$cache_key = $domain.$path;
$md5 = md5($cache_key);

$file_path = $cache_root.'/';
$offset = 0;
foreach ($levels as $level){
    $file_path .= substr($md5,-$offset-$level,$level).'/';
    $offset += $level;
}
$file_path .= $md5;

if(!is_dir($cache_root)){
    http_response_code(500);
    echo json_encode(['success'=>false,'error'=>'缓存目录不存在'],JSON_UNESCAPED_UNICODE);
    exit;
}

if(!file_exists($file_path)){
    http_response_code(404);
    echo json_encode(['success'=>false,'error'=>'缓存文件不存在'],JSON_UNESCAPED_UNICODE);
    exit;
}

if(!is_writable($file_path)){
    http_response_code(500);
    echo json_encode(['success'=>false,'error'=>'无权限删除缓存文件'],JSON_UNESCAPED_UNICODE);
    exit;
}

@unlink($file_path);

@rmdir(dirname($file_path));
@rmdir(dirname(dirname($file_path)));

echo json_encode([
    'success'=>true,
    'message'=>'缓存已清除'
],JSON_UNESCAPED_UNICODE);

五、必须理解的关键配置(非常重要)

1️⃣ cache_root 必须一致

需要与你的 Nginx 配置完全相同:

proxy_cache_path /www/cache levels=1:2 keys_zone=wp:100m;

那么:

$cache_root = '/www/cache';

2️⃣ domain 必须匹配 cache key

如果你使用:

proxy_cache_key $host$uri$is_args$args;

那么:

$domain = 'example.com';

否则 100% 找不到缓存文件


3️⃣ levels 必须一致

levels=1:2

对应:

$levels = [1,2];

否则路径计算错误。

如果是 WordPress 网站的反代,强烈建议参考:WordPress Nginx 反向代理缓存配置详解与完整示例


六、为什么这个方法一定有效?

理解这一点非常关键。

Nginx 的缓存结构:

cache/
 ├─ a/
 │   └─ bc/
 │       └─ md5缓存文件

缓存文件名其实是:

md5(proxy_cache_key)

而这个 PHP 脚本做的事情只有一件:

复现 Nginx 的缓存路径计算逻辑。

然后:

unlink()

直接删除。

没有模块参与。

没有协议限制。

没有兼容问题。


七、如何调用刷新缓存?

示例:

curl -X PURGE https://example.com/php-purge/post/test/

返回:

{
  "success": true,
  "message": "缓存已清除"
}

即可。


八、WordPress 自动刷新

你可以在 WordPress 中:

  • 发布文章
  • 修改文章
  • 删除文章

时自动调用:

/php-purge/URL

实现:

✅ 真正实时反代缓存刷新。

推荐搭配 站长帮 – WordPress CDN 缓存管理插件 实现缓存自动刷新处理。


九、相比 ngx_cache_purge 的优势

对比ngx_cache_purgePHP Purge
是否需编译
兼容发行版
可调试性极强
成功率不稳定极高
可扩展极高

十、真实经验总结

很多站长长期卡在:

“缓存刷新为什么就是不生效?”

实际上问题往往不是配置错误,而是:

  • 模块版本
  • 编译参数
  • cache key 不一致

而 PHP 删除缓存文件,本质上绕开了所有限制。

这也是目前越来越多 WordPress 高性能架构采用的方式。


十一、结语

如果你:

  • 使用 Nginx 反代 WordPress
  • 已开启 proxy_cache
  • 又被缓存刷新折磨

那么这个方案基本可以视为:

Nginx 反代缓存刷新的一次“降维打击”。

简单、稳定、可控。

甚至可以说:

👉 这是比 ngx_cache_purge 更现代的方案。

© 版权声明

本文由站长帮(zhanzhangb.cn)发布,保留所有权利。

未经明确书面许可,不得转载、摘编本站内容。对于侵权行为,我们将保留追究法律责任的权利。