chesio / bc-cache
受Cachify启发的简单磁盘缓存插件。
Requires
- php: ^8.1
- composer/installers: ^1.0 || ^2.0
Requires (Dev)
- brain/monkey: ^2.6
- mockery/mockery: ^1.6
- php-parallel-lint/php-parallel-lint: ^1.3
- php-stubs/wp-cli-stubs: ^2.8
- phpunit/phpunit: ^10.5
- squizlabs/php_codesniffer: ^3.3
- szepeviktor/phpstan-wordpress: ^1.3
This package is auto-updated.
Last update: 2024-09-27 15:16:38 UTC
README
受Cachify启发的现代简单全页缓存插件。
BC Cache没有设置页面 - 它旨在为熟悉.htaccess
文件和WordPress操作和过滤器的网站管理员使用。
BC Cache不仅可以缓存HTML页面,还可以缓存核心XML站点地图。技术上,只要输出生成触发send_headers
钩子,WordPress为前端请求生成的任何内容类型都可以处理。
要求
- 启用了mod_rewrite的Apache Web服务器
- PHP 8.1或更高版本
- WordPress 6.2或更高版本,并开启了美观的永久链接
限制
- 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-Type
、Link
、X-Pingback
、X-Robots-Tag
、X-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_loaded
或after_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更新
-
前端更改
-
帖子状态从发布更改为另一个状态(除了回收站)。注意:发布和回收站相关的操作会单独处理,并且仅针对公开帖子 - 见下文)
-
评论更改
-
网站小工具配置更改
update_option_sidebars_widgets
- 配置保存在sidebars_widgets
选项中,因此每次更新此选项时都会刷新缓存。
帖子及术语的特殊处理
在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) 请求的响应
- 请求是 POST 请求。
- 请求是 GET 请求,具有一个或多个未列入白名单的查询字符串字段。默认情况下,白名单包括 Google 点击 ID、Facebook 点击标识符、Microsoft 点击 ID 和标准的 UTM 参数,但它可以被 过滤。
- 请求不是针对前端页面(即
wp_using_themes
返回false
)。AJAX、WP-CLI 或 WP-Cron 调用的输出永远不会被缓存。 - 请求来自非匿名用户(即已登录的用户、留下评论或访问受密码保护的页面/帖子)。此规则可以根据您的主题是否支持它来调整以忽略 前端用户。
- 请求/响应类型是以下之一:搜索、404、feed、trackback、robots.txt、预览或受密码保护的帖子。
- 致命错误恢复模式是活动的。
DONOTCACHEPAGE
常量已设置并评估为 true。此常量例如由 WooCommerce 在某些页面上 自动设置。bc-cache/filter:skip-cache
过滤器的返回值评估为 true。
重要! 缓存排除规则本质上在两个地方定义
- 在 PHP 代码中(包括
bc-cache/filter:skip-cache
过滤器),规则用于确定当前 HTTP(S) 请求是否应该 写入 缓存。 - 在
.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 请求来自任何已登录用户时,不会从缓存中读取或写入
- 当调用
is_user_logged_in
函数返回 true 时,对 HTTP 请求的响应不会写入缓存。 - 当 HTTP 请求有一个名为
wordpress_logged_in
的 cookie 时,对 HTTP 请求的响应不会从缓存中读取 - 此检查必须在.htaccess
文件中 配置。
当您的主题声明支持 前端用户缓存
自动放宽了第一个检查的一些合理的默认值:任何只有 read
和 customer
权能的用户被视为前端用户,并且他们访问的任何页面都正常写入缓存。如果您愿意,可以 过滤 权能列表或检查的输出。
为了能够放宽第二次检查,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
部分或完全删除该行。
鸣谢
- Sergej Müller & Plugin Kollektiv因Cachify插件的灵感。
- Font Awesome的HDD图标
- Tim Lochmüller为从他的Static File Cache扩展中获取的
.htaccess
配置提供灵感。