chesio/bc-cache

受Cachify启发的简单磁盘缓存插件。

安装: 3

依赖项: 0

建议者: 0

安全性: 0

星标: 9

关注者: 2

分支: 0

开放问题: 1

类型:wordpress-plugin

3.3.2 2024-04-22 11:53 UTC

README

GitHub Actions Packagist

Cachify启发的现代简单全页缓存插件。

BC Cache没有设置页面 - 它旨在为熟悉.htaccess文件和WordPress操作和过滤器的网站管理员使用。

BC Cache不仅可以缓存HTML页面,还可以缓存核心XML站点地图。技术上,只要输出生成触发send_headers钩子,WordPress为前端请求生成的任何内容类型都可以处理。

要求

限制

  • BC Cache未在WordPress多站安装上进行测试。
  • BC Cache未在Windows服务器上测试。
  • BC Cache不支持通过Accept头进行内容协商

安装

BC Cache在WordPress插件目录中不可用,但您可以通过其他几种方式获得它。

使用WP-CLI

如果您已安装WP-CLI,则可以使用单个命令安装(可选激活)BC Cache

wp plugin install [--activate] https://github.com/chesio/bc-cache/archive/master.zip

使用Composer

Composer是管理PHP项目依赖项的绝佳工具。尽管WordPress本身并没有使其易于使用Composer来管理整个WordPress安装,但存在多种 方法来实现。

BC Cache可在Packagist找到,因此只需像往常一样运行composer require chesio/bc-cache即可。

使用Git

主分支始终包含最新稳定版本,因此您可以从插件目录中克隆BC Cache来安装它

cd [your-project]/wp-content/plugins
git clone --single-branch --branch master https://github.com/chesio/bc-cache.git

更新就像

cd [your-project]/wp-content/plugins/bc-cache
git pull

使用Git Updater插件

安装后,BC Cache可以通过Git Updater插件保持最新。要安装它,可以使用下面描述的直接下载方法或使用Git Updater Pro

直接下载

这种方法最不推荐,但它可以在不使用其他工具的情况下工作。您可以从GitHub直接下载BC Cache。请确保将插件解压到正确的目录,并从文件夹名称中删除版本号。

设置

您必须配置Apache网络服务器以提供缓存文件。最常见的方法是将以下行添加到根目录下的.htaccess文件中。这是WordPress自动写入漂亮永久链接配置的相同文件——您必须将以下行放置在漂亮永久链接配置之前。

注意:以下配置假定您已将WordPress安装在wordpress子目录中——如果不是这种情况,只需从以下规则中删除/wordpress部分:RewriteRule .* - [E=BC_CACHE_ROOT:%{DOCUMENT_ROOT}/wordpress]。通常,您可能需要根据服务器环境对以下示例配置进行一些调整。

# BEGIN BC Cache
AddDefaultCharset utf-8

<IfModule mod_rewrite.c>
  RewriteEngine on

  # Configure document root.
  RewriteRule .* - [E=BC_CACHE_ROOT:%{DOCUMENT_ROOT}/wordpress]

  # Get request scheme (either http or https).
  RewriteRule .* - [E=BC_CACHE_SCHEME:http]
  RewriteCond %{ENV:HTTPS} =on [OR]
  RewriteCond %{HTTP:X-Forwarded-Proto} https
  RewriteRule .* - [E=BC_CACHE_SCHEME:https]

  # Clean up hostname (drop optional port number).
  RewriteCond %{HTTP_HOST} ^([^:]+)(:[0-9]+)?$
  RewriteRule .* - [E=BC_CACHE_HOST:%1]

  # Set path subdirectory - its suffix depends on whether URI ends with slash or not.
  RewriteRule .* - [E=BC_CACHE_PATH:%{REQUEST_URI}/@file/]
  RewriteCond %{REQUEST_URI} /$
  RewriteRule .* - [E=BC_CACHE_PATH:%{REQUEST_URI}@dir/]

  # Set request variant (by default there is only empty one).
  RewriteRule .* - [E=BC_CACHE_REQUEST_VARIANT:]

  # Optionally, serve gzipped version of the file.
  RewriteRule .* - [E=BC_CACHE_FILE:index%{ENV:BC_CACHE_REQUEST_VARIANT}]
  <IfModule mod_mime.c>
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule .* - [E=BC_CACHE_FILE:index%{ENV:BC_CACHE_REQUEST_VARIANT}.gz]
  </IfModule>

  # Main rules: serve only GET requests with whitelisted query string fields coming from anonymous users.
  RewriteCond %{REQUEST_METHOD} GET
  RewriteCond %{QUERY_STRING} ^(?:(?:_gl|gclid|gclsrc|fbclid|msclkid|utm_(?:source|medium|campaign|term|content))=[\w\-]*(?:&|$))*$
  RewriteCond %{HTTP_COOKIE} !(wp-postpass|wordpress_logged_in|comment_author)_
  RewriteCond %{ENV:BC_CACHE_ROOT}/wp-content/cache/bc-cache/%{ENV:BC_CACHE_SCHEME}_%{ENV:BC_CACHE_HOST}%{ENV:BC_CACHE_PATH}%{ENV:BC_CACHE_FILE} -f
  RewriteRule .* %{ENV:BC_CACHE_ROOT}/wp-content/cache/bc-cache/%{ENV:BC_CACHE_SCHEME}_%{ENV:BC_CACHE_HOST}%{ENV:BC_CACHE_PATH}%{ENV:BC_CACHE_FILE} [L,NS]

  # Do not allow direct access to cache entries.
  RewriteCond %{REQUEST_URI} /wp-content/cache/bc-cache/
  RewriteCond %{ENV:REDIRECT_STATUS} ^$
  RewriteRule .* - [F,L]
</IfModule>
# END BC Cache

配置

BC缓存没有设置。您可以使用PHP常量、WordPress过滤器主题功能来修改插件行为。

常量

插件的两个高级功能可以取消使用常量。

可以通过将BC_CACHE_WARM_UP_ENABLED常量设置为false来禁用缓存预热功能。

define('BC_CACHE_WARM_UP_ENABLED', false);

文件锁定用于确保操作缓存时操作的原子性。如果您的网络服务器有关于flock()的问题,您可能希望通过将BC_CACHE_FILE_LOCKING_ENABLED常量设置为false来禁用文件锁定。

define('BC_CACHE_FILE_LOCKING_ENABLED', false);

这两个常量必须在插件启动时定义——通常最佳位置是wp-config.php文件。建议在激活插件之前设置这些常量。

过滤器

如果存在设置页面,以下过滤器可能会成为插件设置,因为它们会改变基本功能

  • bc-cache/filter:can-user-flush-cache - 过滤当前用户是否可以清除缓存。默认情况下,任何具有manage_options权限的用户都可以清除缓存。
  • bc-cache/filter:html-signature - 过滤附加到缓存中存储的HTML文件的HTML签名。您可以使用此过滤器删除签名:add_filter('bc-cache/filter:html-signature', '__return_empty_string');
  • bc-cache/filter:cached-response-headers - 过滤由WordPress/PHP生成的HTTP响应头,这些头在创建缓存条目时保留。然后,这些头作为附加响应头发送,与缓存内容一起发送。默认情况下,保留以下头:Content-TypeLinkX-PingbackX-Robots-TagX-BC-Cache-Generated。请注意,Content-Type头对于正确交付缓存内容至关重要,因此始终保留。
  • bc-cache/filter:cache-generation-timestamp-format - 过滤缓存生成时间戳的格式。此时间戳包含在HTML签名中,并在X-BC-Cache-Generated HTTP响应头中。值必须是wp_date()的有效$format参数。

高级函数的过滤器

以下过滤器可用于调整自动缓存清除

  • bc-cache/filter:flush-hooks - 过滤触发缓存清除的操作列表。过滤器在注册到init动作的钩子中执行,优先级为10,因此请确保您在较早注册钩子(例如在plugins_loadedafter_setup_theme动作中)。
  • bc-cache/filter:is-public-post-type - 过滤给定帖子类型是否应被视为公共的。公共帖子类型项目的发布或删除将触发自动缓存清除,但相关的动作钩子不能使用bc-cache/filter:flush-hooks过滤器进行调整,您必须使用此过滤器。
  • bc-cache/filter:is-public-taxonomy - 筛选给定分类是否应视为公开。从公开分类创建、删除或编辑术语将触发自动缓存刷新,但无法通过bc-cache/filter:flush-hooks筛选器调整相关动作钩子,您必须使用此筛选器。

以下筛选器可以用于扩展缓存排除列表或允许某些查询字符串参数

  • bc-cache/filter:skip-cache - 筛选当前HTTP(S)请求的响应是否应该被缓存。筛选器仅在未匹配到内置跳过规则时执行 - 这意味着您不能使用此筛选器覆盖内置跳过规则,只能添加您自己的规则。
  • bc-cache/filter:query-string-fields-whitelist - 筛选不阻止缓存写入的查询字符串字段列表。

以下筛选器对于设置请求变体是必要的

  • bc-cache/filter:request-variant - 筛选当前HTTP请求的请求变体名称。
  • bc-cache/filter:request-variants - 筛选所有可用的请求变体列表。如果您使用变体并且希望在缓存查看器中获取完整且适当的信息,则应使用此筛选器。

以下筛选器可以用于调整缓存预热

  • bc-cache/filter:cache-warm-up-initial-url-list - 筛选要包括在预热中的初始URL列表。此筛选器用于简化默认处理:如果它返回一个数组(即使是空数组),则不会从XML站点图中读取任何URL。
  • bc-cache/filter:cache-warm-up-final-url-list - 筛选要包括在预热中的最终URL列表。
  • bc-cache/filter:cache-warm-up-invocation-delay - 筛选缓存刷新和预热调用之间的时间(以秒为单位)。
  • bc-cache/filter:cache-warm-up-run-timeout - 设置预热爬虫在单个WP-Cron调用中允许运行的时间(以秒为单位)。此值不能大于WP_CRON_LOCK_TIMEOUT常量的值。请注意,爬虫只有在达到此限制后才会停止。这意味着例如,即使超时设置为0,也发送了一个HTTP请求。
  • bc-cache/filter:cache-warm-up-request-arguments - 筛选在预热期间运行的HTTP请求的参数列表

以下筛选器仅在您的主题声明支持前端用户缓存时才有用

  • bc-cache/filter:frontend-user-capabilities - 筛选前端用户的权限列表。
  • bc-cache/filter:is-frontend-user - 筛选当前用户是否为前端用户。
  • bc-cache/filter:frontend-user-cookie-name - 筛选前端用户cookie的名称。
  • bc-cache/filter:frontend-user-cookie-value - 筛选前端用户cookie的内容。

主题功能

某些高级功能必须由您的主题支持,并且仅在主题明确声明支持特定功能时才处于活动状态

  • add_theme_support('bc-cache', 'caching-for-frontend-users'); - 激活前端用户缓存

自动缓存刷新

以下核心操作会自动刷新缓存。动作列表可以使用bc-cache/filter:flush-hooks筛选器进行筛选。

帖子及术语的特殊处理

在WordPress中,帖子可以用来存储各种类型的数据 - 包括在任何前端方式中都不展示的数据。为了使缓存刷新尽可能合理,当一个帖子被发布或移至回收站时,只有在帖子类型是 公开的 的情况下才会刷新缓存。您可以使用 bc-cache/filter:is-public-post-type 过滤器 来覆盖特定帖子类型是否被视为公开以用于缓存刷新。

注意:将帖子状态更改为 草稿未来待定 总会触发缓存刷新(无论帖子类型如何)。

术语(分类法)以类似的方式进行处理 - 当术语创建、删除或编辑时,会自动刷新缓存,但仅限于公开分类法的术语。您可以使用 bc-cache/filter:is-public-taxonomy 过滤器 来覆盖特定分类法是否应被视为公开。

程序化刷新缓存

如果您想从您的代码中刷新 BC Cache 缓存,只需调用 do_action('bc-cache/action:flush-cache')。注意,此操作在执行 init 钩子(优先级为 10)后可用。

计划缓存刷新

使用 WP-Cron 可以轻松实现 BC Cache 缓存按给定计划刷新 - 您只需将 bc-cache/action:flush-cache 操作连接到计划事件。以下 WP-CLI 命令设置 WP-Cron 事件,在午夜触发缓存刷新

wp cron event schedule 'bc-cache/action:flush-cache' midnight daily

缓存排除

如果以下条件中的任何一个评估为真,BC Cache 将不会缓存对 HTTP(S) 请求的响应

  1. 请求是 POST 请求。
  2. 请求是 GET 请求,具有一个或多个未列入白名单的查询字符串字段。默认情况下,白名单包括 Google 点击 IDFacebook 点击标识符Microsoft 点击 ID 和标准的 UTM 参数,但它可以被 过滤
  3. 请求不是针对前端页面(即 wp_using_themes 返回 false)。AJAX、WP-CLI 或 WP-Cron 调用的输出永远不会被缓存。
  4. 请求来自非匿名用户(即已登录的用户、留下评论或访问受密码保护的页面/帖子)。此规则可以根据您的主题是否支持它来调整以忽略 前端用户
  5. 请求/响应类型是以下之一:搜索、404、feed、trackback、robots.txt、预览或受密码保护的帖子。
  6. 致命错误恢复模式是活动的。
  7. DONOTCACHEPAGE 常量已设置并评估为 true。此常量例如由 WooCommerce 在某些页面上 自动设置
  8. bc-cache/filter:skip-cache 过滤器的返回值评估为 true。

重要! 缓存排除规则本质上在两个地方定义

  1. 在 PHP 代码中(包括 bc-cache/filter:skip-cache 过滤器),规则用于确定当前 HTTP(S) 请求是否应该 写入 缓存。
  2. .htaccess 文件中,规则用于确定当前 HTTP(S) 请求是否应该从缓存 服务

当您通过 bc-cache/filter:skip-cache 过滤器添加新的 缓存写入 规则时,您应始终考虑该规则是否也应通过 .htaccess 文件强制执行 缓存读取。一般来说,如果您的规则与请求 URI 没有关系(例如,您检查 cookie 或 User-Agent 字符串),您可能希望在这两个地方都有规则。同样适用于 bc-cache/filter:query-string-fields-whitelist 过滤器 - 任何额外的白名单字段将不再阻止 缓存写入,但除非它们集成到相应的 .htaccess 文件中的规则中,否则仍然会阻止 缓存读取

缓存查看器

可以通过 缓存查看器 管理页面(在 工具 下)检查缓存内容(由任何具有 manage_options 权能的用户)。能够清除缓存的用户可以删除单个缓存条目。

您可能在缓存查看器中遇到有关缓存文件总大小与缓存文件夹中文件总大小不同的警告 - 这通常意味着您未能通过 bc-cache/filter:request-variants 过滤器正确提供所有可用的 请求变体 列表。

前端用户和缓存

注意:前端用户是任何尽管可以通过 wp-login.php 登录但无权访问 /wp-admin 区域的用户。尽管实现细节不假设任何特定的插件,但以下文本是针对 WooCommerce(以及注册客户作为前端用户)编写的。

根据您的主题,向前端用户提供的 HTML 可以与向匿名用户提供的 HTML 相同。此类主题通常通过 JavaScript 调用获取任何个性化内容(如添加到购物车的项目)。在这种情况下,没有理由排除前端用户从全页缓存中。

但是有一个问题...

与一些其他内容管理系统不同,WordPress 不区分后端和前端用户。相同的身份验证机制用于验证后端用户(如商店管理员)和前端用户(如商店客户)。事实上,您不能使用用于商店管理员账户的同一电子邮件地址来创建测试客户账户。

BC Cache 默认情况下,当 HTTP 请求来自任何已登录用户时,不会从缓存中读取或写入

  1. 当调用 is_user_logged_in 函数返回 true 时,对 HTTP 请求的响应不会写入缓存。
  2. 当 HTTP 请求有一个名为 wordpress_logged_in 的 cookie 时,对 HTTP 请求的响应不会从缓存中读取 - 此检查必须在 .htaccess 文件中 配置

当您的主题声明支持 前端用户缓存

自动放宽了第一个检查的一些合理的默认值:任何只有 readcustomer 权能的用户被视为前端用户,并且他们访问的任何页面都正常写入缓存。如果您愿意,可以 过滤 权能列表或检查的输出。

为了能够放宽第二次检查,BC缓存在前端用户登录时设置了一个额外的会话cookie。处理登录cookie的.htaccess文件规则必须按以下方式扩展

# The legacy rule is replaced by 3 rules below:
# RewriteCond %{HTTP_COOKIE} !(wp-postpass|wordpress_logged_in|comment_author)_
RewriteCond %{HTTP_COOKIE} !(wp-postpass|comment_author)_
RewriteCond %{HTTP_COOKIE} !wordpress_logged_in_ [OR]
RewriteCond %{HTTP_COOKIE} bc_cache_is_fe_user=true

这样,缓存页面也可以供前端用户使用。cookie名称和内容可以通过指定的过滤器进行调整——确保在更改它们时相应地调整.htaccess规则。

请求变体

有时,相同的URL会提供不同的响应体,通常是在设置特定cookie或由特定浏览器/机器人发起请求时。在这种情况下,BC缓存允许定义请求变体,并基于配置的条件缓存/提供不同的响应体。一个典型的例子是,在网站访问者接受隐私政策通知之前,显示隐私政策通知。状态(是否接受cookie政策)通常基于特定cookie的存在来决定。使用请求变体,BC缓存可以为已接受或未接受cookie政策的访问者提供服务。

请求变体配置示例

一个网站有两个变体:一个有cookie通知(cookie_notice_accepted cookie未设置)和一个没有(cookie_notice_accepted cookie已设置)。

当cookie通知被接受时,应设置请求变体名称(以下示例使用Cookie Notice插件的API)

add_filter('bc-cache/filter:request-variant', function (string $default_variant): string {
    return cn_cookies_accepted() ? '_cna' : $default_variant;
}, 10, 1);

add_filter('bc-cache/filter:request-variants', function (array $variants): array {
    $variants['_cna'] = 'Cookie notice accepted';
    return $variants;
}, 10, 1);

还需要扩展默认配置,并相应地设置新的变体

  # Set request variants (default and "cookie notice accepted"):
  RewriteRule .* - [E=BC_CACHE_REQUEST_VARIANT:]
  RewriteCond %{HTTP_COOKIE} cookie_notice_accepted=true
  RewriteRule .* - [E=BC_CACHE_REQUEST_VARIANT:_cna]

重要:变体名称附加到缓存文件名的basename部分,因此在上面示例中,index变为index_cna,而index.gz变为index_cna.gz。为了确保您的设置能够正常工作,请仅使用[a-z0-9_-]范围内的字母作为变体名称。

缓存预热

自版本2以来,插件执行缓存预热,即自动将所有页面存储在缓存中,而无需前端用户访问。明显的优势是,即使是特定页面的第一个访问者,也可以从缓存中提供服务(=快速)。

内部,预热过程连接到WP-Cron,网站在后台进行爬取。这种自动爬取在每次缓存刷新时启动(默认延迟10分钟,但可以配置)。

自版本2.2以来,可以从缓存查看器立即触发缓存预热。此外,可以通过以下WP-CLI命令从命令行预热缓存:wp bc-cache warm-up

为了使预热正常工作

  • 网站必须提供XML站点地图(s)。XML站点地图的URL必须在robots.txt文件中宣传或必须是(默认)<home-url>/sitemap.xml。支持XML站点地图索引,但不递归。
  • 如果使用请求变体,则应使用bc-cache/filter:cache-warm-up-request-arguments过滤器来修改任何非默认URL变体的HTTP请求的参数,以便网站对这类请求生成正确的响应。
  • 强烈建议将WP-Cron连接到系统任务调度器以提高性能。

缓存预热配置示例

在最后一次缓存刷新后仅5分钟启动缓存预热

add_filter('bc-cache/filter:cache-warm-up-invocation-delay', function (): int { return 5 * MINUTE_IN_SECONDS; }, 10, 0);

仅允许每个WP-Cron调用一个预热HTTP请求

add_filter('bc-cache/filter:cache-warm-up-run-timeout', '__return_zero', 10, 0);

修改HTTP请求的参数,以获取接受cookie通知的页面变体(有关上下文,请参阅请求变体配置示例

add_filter('bc-cache/filter:cache-warm-up-request-arguments', function (array $args, string $url, string $request_variant): array {
    if ($request_variant === '_cna') {
        $args['cookies'] = [
            'cookie_notice_accepted' => 'true',
        ];
    }
    return $args;
}, 10, 3);

WP-CLI命令

您可以使用WP-CLI来删除特定帖子/页面的缓存,刷新整个缓存,运行缓存预热,获取大小信息,甚至列出所有缓存条目。BC Cache注册了以下子命令的bc-cache命令

  • delete <post-id> - 删除给定ID的帖子/页面的缓存数据(所有请求变体)
  • remove <url> - 删除给定URL的缓存数据(所有请求变体)
  • flush - 清空整个缓存
  • warm-up - 运行缓存预热
  • size [--human-readable] - 获取缓存目录的可见大小,可选以可读格式
  • list [<column>...] [--format=<format>] [--plain] [--sort-by=<column>] - 列出缓存条目,可选按指定格式或排序

与第三方插件和工具集成

Autoptimize

Autoptimize是一个通过聚合、压缩、缓存等优化脚本和样式的非常流行的插件。BC Cache在Autoptimize缓存被清除时自动清除其缓存。

Cookie Notice

Cookie Notice是一个流行的插件,用于显示简单的、可定制的网站横幅,有助于满足某些cookie同意要求。BC Cache在Cookie Notice横幅配置更改时自动清除其缓存。

7G防火墙

如果您在网站上安装了Jeff Starr的7G防火墙,您可能需要修改7G:[REQUEST URI]部分中的规则,以防止访问.gz文件(注意以下代码片段已被省略以增强可读性...

RewriteCond %{REQUEST_URI} (\.)(7z|...|git|gz|hg|...|zlib)$ [NC,OR]

如果您看到403错误而不是缓存页面,您必须从上面的RewriteCond行中删除|gz部分或完全删除该行。

鸣谢