ThinkPHP中HTTP缓存需通过控制器header()、模板注入、中间件、禁用session干扰及Web服务器配置五种方式协同控制;核心是确保Cache-Control、Expires、ETag等头在输出前正确发送,并规避session自动覆盖。

如果您在使用ThinkPHP开发Web应用时发现浏览器反复请求相同资源、服务端未正确响应缓存协商头,或页面无法按预期复用本地副本,则可能是HTTP缓存控制未正确配置。以下是ThinkPHP中配置HTTP缓存控制的具体方法:
一、通过控制器设置Cache-Control与Expires头
该方式适用于对特定动态路由或接口响应实施细粒度的客户端缓存策略,由PHP脚本主动发送标准HTTP缓存头,直接作用于当前响应。
1、在控制器操作方法中,于任何输出前调用header()函数设置缓存指令。
2、设置强缓存策略,允许浏览器在3600秒内直接复用本地副本:header("Cache-Control: public, max-age=3600");
立即学习“PHP免费学习笔记(深入)”;
3、同时补充Expires头以兼容老旧客户端:header("Expires: " . gmdate("D, d M Y H:i:s", time() + 3600) . " GMT");
4、若需禁止浏览器缓存(如调试阶段或敏感操作),使用:header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
二、在模板输出前统一注入缓存头
该方式适用于整站模板渲染场景,确保所有通过View::fetch()输出的HTML页面默认携带一致的缓存策略,避免在每个控制器中重复编写header逻辑。
1、打开应用公共文件common.php或入口文件public/index.php。
2、在框架初始化完成、模板尚未输出前插入缓存头设置代码。
3、判断当前请求是否为HTML类型响应:if (request()->isGet() && request()->accepts('html')) {
4、设置页面级缓存策略:header("Cache-Control: public, max-age=1800");
5、添加ETag支持以启用协商缓存(需配合内容哈希):header("ETag: \"" . md5($content) . "\"");
三、利用中间件拦截并注入缓存响应头
该方式将缓存控制逻辑解耦至中间件层,支持按路由规则、请求方法、响应状态码等条件动态决策,适合中大型项目维护统一缓存策略。
1、创建中间件类,例如app/middleware/HttpCacheMiddleware.php。
2、在handle方法中获取响应对象:$response = $next($request);
3、针对200状态且Content-Type为text/html的响应追加头信息:if ($response->getCode() === 200 && strpos($response->getHeader('Content-Type'), 'text/html') !== false) {
4、设置缓存有效期为1小时并启用公共缓存:$response->header('Cache-Control', 'public, max-age=3600');
5、注册该中间件到全局或特定路由分组的middleware.php配置中。
四、禁用Session自动触发的no-cache行为
ThinkPHP默认启用session_start()会导致PHP隐式发送Cache-Control: no-cache响应头,覆盖手动设置的缓存策略,必须显式干预才能生效。
1、检查控制器或公共逻辑中是否提前调用了session_start()或facade\Session::start()。
2、若无需会话功能,直接移除相关调用语句。
3、若必须使用会话,应在session_start()之后立即重写缓存头:session_write_close(); header("Cache-Control: public, max-age=3600");
4、确认header()调用发生在任何输出(包括空格、BOM、echo)之前,否则将触发“headers already sent”错误。
五、配置静态资源的Apache/Nginx缓存规则
该方式不依赖PHP执行,由Web服务器直接处理静态文件(CSS、JS、图片等)的缓存响应,性能最优,适用于生产环境部署。
1、若使用Apache,在项目根目录.htaccess文件中启用mod_expires模块配置。
2、添加静态资源缓存规则:ExpiresByType text/css "access plus 1 month"
3、若使用Nginx,在server块中配置location匹配规则:location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; }
4、确保Web服务器已启用对应模块(Apache需LoadModule expires_module modules/mod_expires.so;Nginx需编译含http_ssl_module)。



















