ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Yii 2 页面缓存实战指南:用 PageCache 过滤器缓存整页输出

Yii 2 页面缓存实战指南:用 PageCache 过滤器缓存整页输出 Yii 2 页面缓存实战指南用 PageCache 过滤器缓存整页输出【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址: https://gitcode.com/gh_mirrors/yi/yii2页面缓存Page Caching是 Yii 2 在服务器端缓存整页输出的机制当同一页面再次被请求时直接返回缓存内容而不再重新执行控制器逻辑、渲染视图生成页面。本文以官方指南 caching-page.md含日文版 docs/guide-ja/caching-page.md为核心结合框架源码 PageCache 与单元测试 PageCacheTest讲解如何用yii\filters\PageCache动作过滤器配置缓存时长、语言变体与数据库依赖并深入剖析其底层工作原理与实战注意事项。读完本文你将能够为指定 action 快速启用整页缓存并针对多语言、数据变更等场景进行精细化控制。什么是页面缓存页面缓存指在服务器端缓存整个页面的内容。与数据缓存缓存数据库查询结果、配置等基础数据和片段缓存只缓存页面中的某个片段不同页面缓存直接保存最终渲染出的完整 HTML 输出。当后续请求到达时系统直接从缓存中取出内容返回省去了再次执行 action、查询数据库、渲染视图的整个链路是提升高流量页面响应速度的有效手段。Yii 2 官方缓存体系包含四个层次详见 caching-overview.md数据缓存Data Caching片段缓存Fragment Caching页面缓存Page Caching本文主题HTTP 缓存HTTP Caching页面缓存在 Yii 2 中由[[yii\filters\PageCache]]实现它是一个动作过滤器action filter通过响应控制器controller的EVENT_BEFORE_ACTION事件参与 action 执行流程在 action 执行前判断缓存是否有效并在响应发送后把内容写入缓存。基础用法在控制器中启用页面缓存页面缓存以动作过滤器的形式在控制器类的behaviors()方法中声明。官方指南给出的最小可用示例public function behaviors() { return [ [ class yii\filters\PageCache, only [index], duration 60, variations [ \Yii::$app-language, ], dependency [ class yii\caching\DbDependency, sql SELECT COUNT(*) FROM post, ], ], ]; }这段配置的含义only [index]页面缓存仅作用于indexactionduration 60页面内容最多缓存 60 秒variations [\Yii::$app-language]按当前应用语言区分缓存版本不同语言各存一份dependency配置一个基于 SQL 查询结果的依赖yii\caching\DbDependency当post表的总行数发生变化时缓存自动失效。上述全部配置项都能在 PageCache.php 的公共属性中找到对应声明下面逐一深入讲解。核心属性逐项解析作用范围only与exceptonly和except定义过滤器作用于哪些 action它们继承自基类 ActionFilteronly过滤器仅应用于列出的 action ID未设置时应用于所有 actionexcept过滤器不应用于列出的 action ID若某 action 同时出现在only与except中则不生效except优先自 2.0.9 起支持通配符例如only [site/*]。匹配逻辑实现在 ActionFilter::isActive()内部通过StringHelper::matchWildcard()进行通配符匹配。注意当过滤器挂载在模块上时action ID 需包含子模块 ID 和控制器 ID。缓存时长durationduration指定缓存数据的有效秒数默认值为60。在 PageCache.php 的注释中明确设置为0表示缓存永不过期。该值最终作为参数传给缓存组件的set()方法见cacheResponse()中$this-cache-set($this-calculateCacheKey(), $data, $this-duration, $this-dependency);。使用duration 0时缓存内容只有在dependency发生变化时才会失效务必配合依赖使用否则页面将长期停留在旧版本。缓存变体variationsvariations指定导致缓存内容产生差异的因素列表每个因素是一个标量值如语言、GET 参数。例如多语言应用中同一份视图代码会生成不同语言的页面就可以按Yii::$app-language区分缓存variations [ \Yii::$app-language, ],自 2.0.48 起variations还可以传入匿名函数动态生成变体这在需要读取User组件其解析时机早于 PageCache 过滤器时尤其有用variations function () { return [ Yii::$app-language, Yii::$app-user-id, ]; },回调必须返回数组。该能力在 calculateCacheKey() 中实现若variations是Closure则先执行回调取回数组再与缓存键合并单元测试 testClosureVariations() 验证了闭包返回数组与字符串两种情况的键拼接行为。缓存依赖dependencydependency可以是yii\caching\Dependency对象也可以是创建依赖对象的配置数组。依赖用于在数据变化时主动使缓存失效而不必等待duration到期。官方示例使用DbDependencydependency [ class yii\caching\DbDependency, sql SELECT MAX(updated_at) FROM post, ],这个配置会让输出缓存依赖于所有文章的最近修改时间——只要有任何文章被修改缓存立即失效。从源码看DbDependency 提供三个属性db数据库连接对象或应用组件 ID默认db、sql查询语句必填缺省会抛出InvalidConfigException、params绑定到 SQL 的参数数组。其原理是执行sql取第一行结果作为依赖数据写入缓存时保存该结果读取时重新执行 SQL 并比较结果是否变化这由基类 Dependency::isChanged() 完成。提示当同时启用cacheCookies或cacheHeaders时依赖会被求值两次cookie/header 与页面内容分开存储。此时建议为依赖开启reusable属性使同一请求内依赖数据只生成一次以节省性能开销见 PageCache.php 与 Dependency。开关enabledenabled默认true用于按条件整体开关页面缓存。典型场景是表单页只在首次 GET 请求时缓存POST 提交后的页面不缓存避免缓存到含用户输入的表单enabled Yii::$app-request-isGet,在beforeAction()开头若enabled为false则直接放行PageCache.php。单元测试 cacheTestCaseProvider 中的disabled用例验证了关闭后缓存不会被写入。按路由区分varyByRoutevaryByRoute默认true决定缓存是否按路由controller ID action ID区分。在 calculateCacheKey() 中缓存键以[yii\filters\PageCache]开头若varyByRoute为true则追加Yii::$app-requestedRoute。测试 testVaryByRoute() 证明开启时不同 action 的缓存互不干扰关闭时则共享同一份缓存。缓存组件cachecache指定使用的缓存对象或应用组件 ID默认值为cache即Yii::$app-cache组件。在beforeAction()中通过Instance::ensure()解析为实现了yii\caching\CacheInterface的实例。自 2.0.2 起也支持直接传入配置数组来创建缓存对象见 PageCache.php。Cookie 与 Header 的缓存cacheCookies/cacheHeaderscacheCookies默认false是否缓存全部 Cookie或传一个 Cookie 名称数组指定白名单。缓存 Cookie 需极其谨慎可能把敏感或私有数据泄露给不该看到它的用户cacheHeaders默认true是否缓存全部 HTTP 响应头或传一个区分大小写的 Header 名称数组指定白名单。若 Header 含敏感信息应只白名单化可缓存的 Header。这两个特性自 2.0.4 引入存储与恢复逻辑分别在insertResponseCookieCollectionIntoData()/insertResponseHeaderCollectionIntoData()与restoreResponse()中实现。测试 PageCacheTest 用多组用例覆盖了allCookies、someCookies、noCookies、allHeaders、someHeaders、noHeaders、originalNameHeaders以及二者组合的全部场景。视图组件viewview指定用于缓存/渲染的视图组件默认取应用级Yii::$app-view在init()中赋值见 PageCache.php。动态内容见下文的占位符替换依赖该视图组件。缓存键的构成原理页面缓存的键由 calculateCacheKey() 生成格式为[yii\filters\PageCache, 请求路由varyByRoutetrue 时, ...variations 变体...]测试 testCalculateCacheKey() 给出了明确的键形设置variations [ru]且路由为test时键为[yii\filters\PageCache, test, ru]未设置variations时键为[yii\filters\PageCache, test]。此外写入缓存的每条数据都带有cacheVersion字段常量PAGE_CACHE_VERSION 1用于在缓存数据结构不兼容时自动淘汰旧版本数据PageCache.php。底层工作流程缓存命中与未命中PageCache 是动作过滤器其核心逻辑在beforeAction()与cacheResponse()中缓存未命中beforeAction()返回truePageCache.php将当前过滤器注册为动态内容感知对象pushDynamicContent开启输出缓冲ob_start()在Response::EVENT_AFTER_SEND事件上挂接cacheResponseaction 正常执行并渲染页面响应发送完毕后cacheResponse()捕获缓冲内容连同响应格式、版本、状态码、状态文本、Header、Cookie 及动态内容占位符一起存入缓存键为calculateCacheKey()过期时间为duration并携带dependency。缓存命中beforeAction()返回false调用restoreResponse()PageCache.php从缓存数据中恢复format、version、statusCode、statusText、content等响应属性并合并 Header 与 Cookie若存在动态内容占位符则重新执行动态 PHP 代码替换占位符由于beforeAction()返回falseaction 主体不再执行页面直接由缓存输出。值得一提的扩展点自 2.0.11 起可重写beforeCacheResponse()返回false取消本次缓存返回数组则额外存入自定义数据与afterRestoreResponse()恢复完成后、响应发送前的收尾钩子见 PageCache.php。页面缓存与片段缓存的异同页面缓存与片段缓存非常相似都支持duration、dependencies、variations、enabled等选项。二者的核心区别在于实现形态维度页面缓存片段缓存实现载体动作过滤器yii\filters\PageCache小部件 Widgetyii\widgets\FragmentCache缓存粒度整个页面页面中的某个片段使用位置控制器behaviors()视图模板beginCache()/endCache()生效时机action 执行前拦截视图渲染过程中页面缓存可以与片段缓存、动态内容组合使用。在页面缓存内部使用片段缓存时内层片段有自己的缓存键与失效策略即使外层页面缓存有效内层动态内容View::renderDynamic()注入的 PHP 代码片段也会在每个请求重新执行。这一机制建立在yii\base\DynamicContentAwareInterface与DynamicContentAwareTrait自 2.0.14 起之上PageCache 通过 DynamicContentAwareTrait 实现占位符的注册与替换缓存时以占位符代替动态内容恢复缓存时重新执行占位符对应的 PHP 语句详见 PageCache::restoreResponse() 与updateDynamicContent()。适用前提与实战注意事项只缓存 GET 类请求页面缓存会把首次生成的响应整体保存并复用对包含表单提交、写操作、个性化数据的页面需谨慎可通过enabled按请求类型开关敏感数据隔离默认不缓存 CookiecacheCookies false但会缓存 HeadercacheHeaders true凡涉及用户私有数据的场景应显式配置白名单或关闭对应开关多语言站点务必通过variations按语言区分缓存避免不同语言用户看到彼此的缓存页面频繁变化的数据用dependency如DbDependency代替短duration在数据变化时即时失效兼顾新鲜度与命中率duration 0与依赖配合永不过期缓存必须配合可靠依赖否则内容无法更新运行环境要求本框架面向 PHP 应用页面缓存依赖服务器端会话与缓存组件如 caching-data.md 所述的文件、数据库、Memcache、Redis 等缓存后端生产环境需先配置好cache应用组件。源码与测试验证路径如果你想深入验证以上结论可以按如下路径继续阅读当前仓库过滤器实现framework/filters/PageCache.php过滤器基类only/except匹配逻辑framework/base/ActionFilter.php数据库依赖framework/caching/DbDependency.php依赖基类reusable、isChanged()framework/caching/Dependency.php动态内容机制framework/base/DynamicContentAwareTrait.php单元测试覆盖 enabled、Cookie/Header 白名单、varyByRoute、variations、dependency、缓存键tests/framework/filters/PageCacheTest.php相关官方文档caching-fragment.md、caching-overview.md、structure-filters.md【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址: https://gitcode.com/gh_mirrors/yi/yii2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表