在为 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_purge | PHP Purge |
|---|---|---|
| 是否需编译 | ✅ | ❌ |
| 兼容发行版 | ❌ | ✅ |
| 可调试性 | 差 | 极强 |
| 成功率 | 不稳定 | 极高 |
| 可扩展 | 低 | 极高 |
十、真实经验总结
很多站长长期卡在:
“缓存刷新为什么就是不生效?”
实际上问题往往不是配置错误,而是:
- 模块版本
- 编译参数
- cache key 不一致
而 PHP 删除缓存文件,本质上绕开了所有限制。
这也是目前越来越多 WordPress 高性能架构采用的方式。
十一、结语
如果你:
- 使用 Nginx 反代 WordPress
- 已开启 proxy_cache
- 又被缓存刷新折磨
那么这个方案基本可以视为:
Nginx 反代缓存刷新的一次“降维打击”。
简单、稳定、可控。
甚至可以说:
👉 这是比 ngx_cache_purge 更现代的方案。
