后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载导读本指南围绕 Yii2 框架内置的yii\filters\HttpCache动作过滤器系统讲解如何在不增加服务端负担的前提下利用 HTTP 协议原生的客户端缓存机制Last-Modified、ETag、Cache-Control三类响应头显著减少同一页面的重复渲染与网络传输。阅读本文后你将掌握HttpCache的完整配置方法、回调签名约定、底层判定逻辑源码级别、与会话缓存的冲突处理方案以及它带来的 SEO 收益能够直接在生产控制器中落地可运行的缓存策略。一、客户端缓存与服务器端缓存互补的加速手段Yii2 之前的章节参见 caching-overview.md、caching-page.md所介绍的数据缓存、片段缓存与页面缓存都属于服务器端缓存——内容生成后仍要从服务器传输给客户端。与之相对Web 应用还可以利用客户端缓存client-side caching让浏览器或代理在本地复用已获取的页面内容从而同时省下服务器端生成页面与通过网络传输页面内容两部分开销。在 Yii2 中启用客户端缓存的方式非常简洁把 [[yii\filters\HttpCache]] 配置为控制器动作action的过滤器filter即可。需要强调的是HttpCache只对GET与HEAD请求生效因为只有这两类请求才可能被客户端安全地缓存见 framework/filters/HttpCache.php 中beforeAction()对请求方法的判断非 GET/HEAD 直接放行它专门管理三类与缓存相关的 HTTP 响应头[[yii\filters\HttpCache::lastModified|Last-Modified]][[yii\filters\HttpCache::etagSeed|Etag]][[yii\filters\HttpCache::cacheControlHeader|Cache-Control]]作为过滤器家族的一员HttpCache通过ActionFilter基类挂载在控制器的behaviors()方法中配合only/except精确圈定作用范围相关通用说明可参见 structure-filters.md。二、Last-Modified头部基于时间戳的命中判定2.1 工作原理Last-Modified响应头用一个时间戳告诉客户端这个页面最近一次修改的时间。客户端通常是浏览器在之后的请求中携带If-Modified-Since请求头回传该时间服务器比对后若发现页面未变化就返回304 Not Modified状态码不重新渲染、不传输正文客户端直接使用本地缓存。2.2 配置方式与回调签名要启用Last-Modified只需配置 [[yii\filters\HttpCache::lastModified]] 属性。该属性必须是返回页面修改时间 UNIX 时间戳的 PHP 可调用对象callable其签名约定如下/** * param Action $action 当前正在处理的动作对象 * param array $params params 属性的值 * return int 代表页面修改时间的 UNIX 时间戳 */ function ($action, $params)其中$params对应HttpCache::params属性可在配置过滤器时额外注入参数用于向回调传递上下文数据详见 framework/filters/HttpCache.php 中$lastModified、$params两个属性的文档注释。2.3 完整示例以文章表最新更新时间作为 Last-Modified下面是最典型的用法——把内容集合的最后修改时间当作页面修改时间public function behaviors() { return [ [ class yii\filters\HttpCache, only [index], lastModified function ($action, $params) { $q new \yii\db\Query(); return $q-from(post)-max(updated_at); }, ], ]; }上述代码通过only [index]将 HTTP 缓存限定在index动作Last-Modified基于post表中updated_at字段的最大值生成。浏览器首次访问index页时服务器正常渲染并返回带Last-Modified的完整响应此后浏览器再次访问时若期间没有任何帖子被修改服务器将直接返回304服务器端渲染与页面内容传输都被跳过。2.4 源码级佐证beforeAction 中的完整判定链从 framework/filters/HttpCache.php 的beforeAction()实现可以看到精确的调用顺序检查$enabled为false时直接放行校验请求方法非 GET/HEAD或lastModified与etagSeed均为空时直接放行若配置了lastModified调用call_user_func($this-lastModified, $action, $this-params)得到时间戳调用sendCacheControlHeader()发送缓存策略头调用validateCache()判断客户端缓存是否仍有效若请求携带If-None-Match则以 ETag 判定且优先于时间戳否则若携带If-Modified-Since则用strtotime(...)解析该头并与$lastModified比较请求时间戳 本地时间戳视为命中缓存有效时设置304状态码并返回false阻止后续动作执行否则照常返回true继续渲染。Last-Modified响应头的格式化输出为gmdate(D, d M Y H:i:s, $lastModified) . GMT符合 HTTP 规范要求的格林尼治标准时间格式。三、ETag头部基于内容哈希的精确缓存3.1 工作原理Entity Tag实体标签简称ETag用页面内容的哈希值表示页面状态内容一旦变化哈希随之改变。服务器把自身生成的哈希与客户端通过If-None-Match请求头回传的哈希比较即可判定页面是否变化、是否需要重新传输比时间戳判定更精确、更灵活。3.2 配置方式与回调签名启用ETag需要配置 [[yii\filters\HttpCache::etagSeed]] 属性一个返回 ETag 哈希种子seed字符串的 PHP 可调用对象签名如下/** * param Action $action 当前正在处理的动作对象 * param array $params params 属性的值 * return string 用于生成 ETag 哈希的种子字符串 */ function ($action, $params)3.3 完整示例以文章标题与内容作为 ETag 种子public function behaviors() { return [ [ class yii\filters\HttpCache, only [view], etagSeed function ($action, $params) { $post $this-findModel(\Yii::$app-request-get(id)); return serialize([$post-title, $post-content]); }, ], ]; }这里将ETag限定在view动作种子由被请求文章通过id查询的title与content序列化而成。浏览器首次访问时正常渲染再次访问且文章标题与内容未变时服务器不重新渲染浏览器直接复用本地缓存。3.4 源码级佐证ETag 的生成算法与弱校验从 framework/filters/HttpCache.php 的generateEtag()可以看到 Yii2 实际采用的哈希算法protected function generateEtag($seed) { $etag . rtrim(base64_encode(sha1($seed, true)), ) . ; return $this-weakEtag ? W/ . $etag : $etag; }即对种子字符串执行SHA-1二进制模式→ Base64 编码并去掉末尾的填充 → 外层包裹英文双引号。同时HttpCache还提供两个值得关注的补充属性自 2.0.8 起引入[[yii\filters\HttpCache::weakEtag|weakEtag]]默认false置为true时生成弱 ETag前缀W/适用于内容语义等价但字节不完全相同的场景符合 RFC 7232 第 2.3 节当etagSeed回调返回null时beforeAction()不会设置ETag响应头测试 tests/framework/filters/HttpCacheTest.php 的testGenerateEtag对此有专门断言。3.5 设计建议与性能警告ETag相比Last-Modified支持更复杂、更精确的缓存策略。例如当站点切换主题时只需在种子表达式中加入主题标识即可让所有页面 ETag 整体失效。但必须警惕ETag 需要在每次请求时重新计算。若种子生成代价过高如复杂的数据库聚合或昂贵的序列化反而会违背HttpCache减少服务端开销的初衷引入不必要负担。因此应尽量选择内容变化时能失效缓存的简单表达式作为种子例如上例中直接复用查询出的字段而不是在回调中再次执行重型计算。3.6 RFC 7232 合规性双头并存时的优先级Note: 依据 RFC 7232若同时配置了ETag与Last-ModifiedHttpCache会同时发送两个响应头。而当客户端同时发送If-None-Match与If-Modified-Since请求头时只有前者If-None-Match会被采纳。这一优先级在源码 framework/filters/HttpCache.php 的validateCache()中有明确体现先检查If-None-Match命中即返回 ETag 比较结果仅在客户端未发送该头时才回退到If-Modified-Since时间戳比较。测试 tests/framework/filters/HttpCacheTest.php 的testValidateCache覆盖了If-None-Match优先于If-Modified-Since、以及通配符*等边界情形。四、Cache-Control头部声明页面级缓存策略Cache-Control响应头用于向客户端浏览器及中间代理声明页面的通用缓存策略——例如是否允许共享缓存、缓存有效时长等。HttpCache通过配置 [[yii\filters\HttpCache::cacheControlHeader]] 属性即可发送自定义值其默认值为Cache-Control: public, max-age3600即允许公共缓存最长缓存 3600 秒1 小时。源码 framework/filters/HttpCache.php 中该属性默认值即为public, max-age3600当显式设为null时sendCacheControlHeader()将不再发送该响应头见同文件 L197-L201。五、会话缓存限制器避免与 PHP Session 的头部冲突5.1 冲突来源当页面使用 Session 时PHP 会根据php.ini中的session.cache_limiter设置自动发送若干缓存相关响应头如Expires、Cache-Control、Last-Modified、Pragma。这些自动头可能与HttpCache精心构造的缓存行为互相干扰甚至直接禁用你想要的缓存效果。5.2 默认行为与自定义为避免冲突HttpCache在默认情况下会自动禁用这些由 PHP 自动发送的缓存头。若想改变此行为可配置 [[yii\filters\HttpCache::sessionCacheLimiter]] 属性取值包括取值含义详见 PHP 手册session_cache_limiter()说明public允许公共缓存通常附带较长的过期时间private仅允许私有浏览器本地缓存private_no_expire私有缓存且不发送Expires头nocache禁用一切缓存每次请求都重新验证源码 framework/filters/HttpCache.php 中该属性默认值为空字符串含义正是关闭 PHP 自动发送缓存头的开关若设为null则不会调用session_cache_limiter()PHP 将按其 INI 配置原样发送缓存头。具体实现位于sendCacheControlHeader()L184-L202当sessionCacheLimiter 且响应头尚未发送、Session 已激活时通过header_remove()移除Expires、Cache-Control、Last-Modified、Pragma四个头再调用Yii::$app-getSession()-setCacheLimiter(...)落实会话缓存限制策略。六、SEO 影响缓存头对搜索引擎爬虫的积极意义搜索引擎的爬虫bot倾向于尊重缓存头。部分爬虫对单域名在单位时间内可抓取的页面数量设有上限因此引入合理的缓存头可以减少爬虫需要真正处理的页面数量从而可能促进站点被更充分地索引。这一收益在页面量大、内容更新不频繁的站点上尤其明显——配合Last-Modified/ETag让爬虫走304分支既能减轻服务器压力也有助于提升抓取效率。七、行为验证从单元测试看 HttpCache 的可靠性仓库中的单元测试 tests/framework/filters/HttpCacheTest.php 对HttpCache的关键行为做了系统覆盖可作为理解与验收缓存配置的参考testDisabledenabled为false时beforeAction()直接返回true即过滤器完全旁路testEmptyPragma使用空字符串作为 ETag 种子时响应中不会出现残留的Pragma头验证了会话缓存限制器的清理逻辑testValidateCache逐条验证If-Modified-Since/If-None-Match的判定矩阵包括时间戳相等命中、哈希不一致未命中、If-None-Match优先、通配符*恒为未命中等场景testGenerateEtag验证 ETag 以双引号包裹、弱 ETag 以W/开头、种子返回null时不发送 ETag 头。八、快速上手清单把HttpCache集成到控制器只需三步在控制器的behaviors()中声明[class yii\filters\HttpCache, ...]并用only/except限定目标动作至少配置lastModified返回 UNIX 时间戳或etagSeed返回种子字符串二者之一——两者都为空时过滤器不生效源码直接放行视需要配置cacheControlHeader默认public, max-age3600与sessionCacheLimiter默认关闭 PHP 自动缓存头并为enabled保留按需动态开关的能力。通过以上配置HttpCache会在每次GET/HEAD请求进入动作前完成缓存校验命中时以304 Not Modified短路响应让客户端复用本地缓存从而真正实现渲染与传输双跳过的高效 HTTP 缓存。赞分享后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载相关推荐Yii2 HTTP 缓存实战借助 HttpCache 过滤器实现 Last-Modified、ETag 与 Cache-Control 客户端缓存Yii2 HTTP 缓存实战借助 HttpCache 过滤器实现 Last Modified、ETag 与 Cache Control 客户端缓存 导读 本指后端Web框架Yii2 HTTP 缓存HttpCache实战指南Last-Modified、ETag 与 Cache-Control 客户端缓存详解Yii2 HTTP 缓存HttpCache实战指南Last Modified、ETag 与 Cache Control 客户端缓存详解 本指南以 Yii后端Web框架Yii 2 HTTP 缓存实战指南用 HttpCache 过滤器实现客户端缓存Last-Modified / ETag / Cache-ControlYii 2 HTTP 缓存实战指南用 HttpCache 过滤器实现客户端缓存Last Modified / ETag / Cache Control H后端Web框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
swagger-codegen 生成 Go 客户端枚举模型全解:以 EnumArrays 为例 swagger-codegen 生成 Go 客户端枚举模型全解:以 EnumArrays 为例 【免费下载链接】swagger-codegen swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAP… · 2026/9/23 13:17:37
淮河流域图实战项目避坑:版本升级后API全变了 淮河流域图实战项目避坑:版本升级后API全变了 上周带新人复盘那个淮河流域图实战项目,我差点没忍住把键盘砸了。刚跑通的代码,换个环境直接报错,控制台一片红。问怎么回事,新人说:“老师,昨天还能跑,今天怎么API全变了?”… · 2026/9/23 13:17:31
面试被问webdl-086原理答不上来?这份保姆级教程帮你破局 面试被问webdl-086原理答不上来?这份保姆级教程帮你破局 面试被问到底层原理,你卡壳了?别慌。很多开发者在简历上写了精通某技术,但真到了面试现场,问到核心机制就哑火。这篇保姆级教程,就是为了解决这个痛点。… · 2026/9/23 13:17:25
Linux环境变量详解:从command not found到永久配置与急救 新装好的Linux,你满怀期待地敲下java,结果终端冷冷回了一句:command not found。别急着怀疑JDK没装好,多半是系统根本没被告知上哪儿找java这个命令。这个“告诉系统去哪儿找”的机制,就是环境变量。今天就把这玩意儿彻… · 2026/9/23 14:11:03
淘宝首屏性能优化避坑指南:从3秒到0.8秒的实战复盘 淘宝首屏性能优化避坑指南:从3秒到0.8秒的实战复盘 官方文档读了一堆,Fiddler抓包也看了,但首页打开还是慢得像蜗牛?别慌,这就是典型的“知道但做不到”。淘宝首屏加载慢,90%的开发者都掉进过同一个坑:… · 2026/9/23 14:11:03
扑克牌识别数据集实战:用YOLO v11将A-K字母识别做到98.7% 简介:面向扑克牌识别项目开发者,提供一套可直接用于YOLOv11训练的规范数据集,覆盖A-K全部13种牌面字母,包含1850张原始图像,整体识别正确率达98.7%。包内共2000个文件,以txt格式标注文件为主(18… · 2026/9/23 14:10:43
猫行为识别实战:CNN图像分类+边缘部署全链路 简介:本资源是一套基于PyTorch实现的猫行为识别实战项目,面向深度学习初学者与计算机视觉实践者,聚焦CNN卷积神经网络在图像分类任务中的完整落地流程。项目涵盖数据预处理、模型训练与GUI交互三大核心环节,支持对多种猫行为图片进… · 2026/9/23 14:10:36
智能问答系统落地:Word文档解析与RAG检索链路实战 简介:面向自然语言处理初学者与AI项目开发者的智能问答系统学习资料,围绕问题理解、知识获取、答案生成与评估等核心模块,系统梳理了智能问答的整体架构与工作流程。内容重点覆盖分词、文本相似度计算等关键算法,详细讲解基于词典… · 2026/9/23 14:10:36
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29