PHP项目CDN回源如何设置缓存规则

wen PHP项目 25

本文目录导读:

PHP项目CDN回源如何设置缓存规则

  1. 核心原则:通过HTTP响应头控制CDN缓存
  2. 在CDN控制台设置缓存规则(以腾讯云/阿里云为例)
  3. PHP动态内容的特殊处理
  4. 验证配置是否生效
  5. 常见问题与排查
  6. 推荐配置模板

在PHP项目中设置CDN回源缓存规则,通常需要从CDN控制台配置源站(PHP服务器)响应头两个层面协同完成,以下是系统化的操作指南和最佳实践。


核心原则:通过HTTP响应头控制CDN缓存

CDN节点是否缓存文件,以及缓存多久,主要取决于源站返回的HTTP响应头(Cache-ControlExpiresLast-Modified等),PHP程序需要主动输出这些头信息。

在PHP中设置缓存头

静态资源(CSS、JS、图片等):

// 设置强缓存:浏览器和CDN均缓存1年
header('Cache-Control: public, max-age=31536000, immutable');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
  • public:允许CDN和中间代理缓存。
  • max-age:缓存生效秒数(31536000秒=1年)。
  • immutable:指示浏览器无需重新验证(仅Chrome/Firefox支持)。

动态HTML页面(可缓存但需更新):

// 缓存10分钟,超过时间需回源验证
header('Cache-Control: public, max-age=600, must-revalidate');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime(__FILE__)) . ' GMT');
  • must-revalidate:缓存过期后必须回源检查文件是否修改。

登录态、个人数据(禁止缓存):

// 绝对不缓存(适合API、用户中心等)
header('Cache-Control: private, no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

使用.htaccess/Nginx配置文件(静态文件更高效)

如果不想修改PHP代码,可在Web服务器层面设置缓存规则:

Apache (.htaccess):

<FilesMatch "\.(css|js|jpg|png|gif|ico|svg|woff2?)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
<FilesMatch "\.(html|php)$">
    Header set Cache-Control "public, max-age=600, must-revalidate"
</FilesMatch>

Nginx (server block):

location ~* \.(css|js|jpg|png|gif|ico|svg|woff2?)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}
location ~* \.(html|php)$ {
    expires 10m;
    add_header Cache-Control "public, must-revalidate";
}

在CDN控制台设置缓存规则(以腾讯云/阿里云为例)

即使源站返回了缓存头,CDN节点也可能需要额外配置来覆盖或强化规则。

设置优先级:CDN缓存规则 > 源站响应头(通常可配置)

大多数CDN支持强制缓存缓存规则优先级

  • 遵循源站:完全按照PHP返回的Cache-Control执行。
  • CDN强制缓存:忽略源站头,强制缓存指定秒数(适合静态资源)。
  • CDN覆盖源站:以CDN规则为准。

典型CDN缓存规则配置

文件类型 CDN缓存时间 回源策略 说明
*.css, *.js, *.jpg 30天 源站返回304则缓存 增量更新时建议加版本号(如style.css?v=2
*.html 10分钟 始终回源验证 内容更新频率高的页面
*.php 0秒(不缓存) 透传 动态PHP脚本通常不缓存
/api/* 不缓存 透传 API接口必须实时更新

高级:忽略URL参数(提升命中率)

如果PHP页面通过?id=123参数动态生成内容,但CDN缓存了不同参数版本,会导致缓存碎片化,建议:

  • 在CDN控制台开启忽略URL参数(按需选择“全部忽略”或“保留指定参数”)。
  • 如果参数影响内容(如分页?page=2),可考虑将参数移入PATH(如/list/2.html),或使用Cookie/Token等方式传递。

PHP动态内容的特殊处理

缓存允许但需及时更新的场景(如新闻列表)

// 输出时记录最后修改时间
$lastModified = 'Wed, 21 Oct 2023 07:28:00 GMT';
header('Last-Modified: ' . $lastModified);
// 检查客户端缓存是否有效
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && 
    strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= strtotime($lastModified)) {
    header('HTTP/1.1 304 Not Modified');
    exit;
}
// 否则正常输出内容

使用ETag(更精确的内容指纹)

$content = getContent();
$etag = md5($content);
header('ETag: "' . $etag . '"');
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && 
    trim($_SERVER['HTTP_IF_NONE_MATCH'], '"') == $etag) {
    header('HTTP/1.1 304 Not Modified');
    exit;
}
echo $content;

验证配置是否生效

检查响应头

使用浏览器开发者工具或curl -I https://yourdomain.com/path

curl -I https://cdn.example.com/static/js/app.js
# 期望看到:
# Cache-Control: public, max-age=31536000
# age: 12345  # CDN节点缓存已存在的时间
# x-cache: HIT  # 表示从CDN缓存命中

回源测试

# 强制从CDN回源(添加特定参数,如 ?timestamp=xxx)
curl -H "Cache-Control: no-cache" https://cdn.example.com/index.html

常见问题与排查

CDN缓存了错误内容(如用户登录态泄漏)

  • 原因:未对动态内容设置privateno-cache
  • 解决:PHP代码中对用户相关URL输出Cache-Control: private, no-store

修改了文件但CDN缓存未刷新

  • 使用版本号:在文件名后加?v=2或直接改名(如style.cssstyle.abc123.css)。
  • CDN刷新:手动刷新CDN节点缓存(控制台操作或API调用)。

PHP动态URL(如/article.php?id=1)命中率低

  • 方案不随用户变化,在CDN控制台开启忽略URL参数(前提是所有参数对内容无影响)。
  • 更好方案:使用URL重写,将/article/1映射到/article.php?id=1,CDN缓存完整的路径。

推荐配置模板

PHP源站(.htaccess或Nginx config)

# 静态资源 - 长期缓存
.css, .js, .jpg, .png, .gif, .ico, .svg, .woff2 → Cache-Control: public, max-age=31536000
# 页面文档 - 短时间缓存
.html, .htm → Cache-Control: public, max-age=600
# PHP动态内容 - 遵循PHP代码中的设置
.php, .php3, .php4 → 不设置通用规则,由代码控制
# 禁止缓存 - API或后台路径
/admin/*, /api/*, /login/* → Cache-Control: private, no-store

CDN控制台: | 路径 | 缓存时间 | 策略 | |-----|---------|------| | *.js?* | 30天 | 强制缓存 | | *.css?* | 30天 | 强制缓存 | | /static/* | 30天 | 强制缓存 | | 其他路径 | 遵循源站 | 回源时传递Accept-Encoding |


  • 静态资源:强制长时间缓存(1年),配合版本号更新。
  • 动态页面:根据更新频率设置短时间缓存(如10分钟),配合Last-Modified/ETag验证。
  • :明确禁止缓存(private, no-store)。
  • 验证:通过响应头中的agex-cache确认CDN缓存命中情况。

遵循“源站输出正确响应头 + CDN控制台规则补充”的策略,即可高效管理PHP项目的CDN回源缓存。

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