PHP不负责静态文件缓存,CDN仅依据Nginx返回的HTTP响应头(如Cache-Control: public)及回源路径是否绕过PHP来决定缓存;若PHP输出含no-cache、Vary: Cookie等头,或回源至/index.php而非静态文件路径,则CDN无法有效缓存。

PHP 本身不负责静态文件缓存,也不该直接参与 CDN 缓存决策;真正起作用的是 Web 服务器(Nginx)发出的响应头 + CDN 回源路径是否绕过 PHP 解释器。
为什么 PHP 输出的静态 HTML 很难被 CDN 缓存
CDN 不看 PHP 源码,只看它收到的 HTTP 响应。一旦 PHP 脚本里调用了 session_start()、setcookie(),或手动输出了 Cache-Control: no-cache、Vary: Cookie 这类头,CDN 就会跳过缓存——哪怕内容完全静态。
- 用
curl -I https://example.com/about.php检查响应头,如果出现Cache-Control: no-store, no-cache, must-revalidate,说明 CDN 根本不会存 - 常见陷阱:框架自动开启 session、模板里混写
<?php echo date('Y'); ?>,导致每次生成的 HTML 实际不同,缓存失效不可控 - PHP 渲染完 HTML 后,必须写入文件系统(如
/public/cache/article-123.html),再由 Nginx 直接返回,而非让 CDN 回源到/index.php
Nginx 配置必须分离静态与动态请求路径
默认 Laravel 或 ThinkPHP 的 try_files $uri $uri/ /index.php?$query_string; 是最大隐患:CDN 回源时所有请求都被打到 PHP,缓存形同虚设。
- 把静态资源路径显式前置匹配,例如
location ^~ /cache/ { try_files $uri =404; } - 再用
location @php { ... }作为兜底,确保只有明确未命中静态文件时才进 PHP - 给静态 HTML 加上
add_header Cache-Control "public, max-age=3600";—— 注意:这行必须在 Nginx 的location块里,不能靠 PHP 的header()函数
CDN 回源地址必须指向纯静态目录
回源设置错一个字符,整个缓存链就断了。CDN 看到的是 Nginx 返回的 200 OK + Cache-Control: public,才真正开始缓存;否则它只当是动态响应,每次都要回源。
立即学习“PHP免费学习笔记(深入)”;
- CDN 控制台里「源站地址」填
https://origin.example.com是错的,应该填https://origin.example.com/cache/或更精确的https://origin.example.com/public/cache/ - 源站 Nginx 的
root必须包含该路径,且权限可读(chown www-data:www-data /path/to/public/cache) - 避免用相对路径写入文件:
file_put_contents('./cache/home.html', $html)容易因工作目录变化失败,改用绝对路径:file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/cache/home.html', $html)
静态资源(JS/CSS/图片)要走独立域名 + immutable 头
这类资源更新频率低、内容稳定,适合长期缓存。但浏览器对 max-age 过长的资源有“不敢更新”心理,所以必须配合内容哈希和 immutable 头。
- Nginx 配置中针对扩展名加头:
location ~* \.(js|css|png|jpg|gif|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } - 前端构建工具(Webpack/Vite)必须启用文件名哈希,如
app.a1b2c3.js,这样更新后 URL 变化,CDN 自动缓存新版本 - 不要给静态资源配
Vary: Accept-Encoding以外的Vary头,否则 CDN 会为每个组合存多份副本,浪费空间且降低命中率
最容易被忽略的一点:CDN 缓存键(Cache Key)默认不包含查询参数,但如果你在静态资源 URL 后加了 ?v=1.2.3,而 CDN 又没配置「忽略查询参数」,就会造成同一文件被缓存多次。要么统一关闭查询参数参与缓存,要么确保所有构建产物都用哈希命名、URL 干净无参。



















