每个人都想要一个速度很快的网站,网站速度越快,用户访问友好度就越好,加快网站响应速度的重要方法之一是开启缓存,而缓存背后的逻辑就是存储信息,更具体一点说,就是找到一个比连接数据库更快的存储信息的地方。
那么在 WordPress 中如何快速缓存 SQL 查询和 HTTP 响应呢?这个时候就要用到 WordPress 的短时缓存(Transients)功能。
什么是短时缓存(Transients)
我们知道 WordPress 缓存有多种类型,比如对象缓存、浏览器缓存、页面缓存甚至数据库缓存,每种类型都有其用途和设置步骤。
那么今天介绍的 Transients API,是 WordPress 用于在页面加载期间临时存储 WordPress 中的信息,Transients 本身是“短暂的”或“临时的”意思,那么 Transients API 可以理解为临时缓存或者短暂缓存的意思,我这里将它翻译成短时缓存,它是 WordPress 用来缓存一些复杂的 SQL 查询和运算结果的最简单的方法。
它给这些需要缓存的数据一个过期时间,并且时间一到就会自动删除,所以在制作 WordPress 插件的时候,需要存储一些有一定生命周期的数据的时候,Transients API 就是最好的选择。
简单说,Transients 是一种非常强大的工具,它不仅可以用来避免对页面内容进行不必要的数据库请求,还可以加快生成复杂标记的速度并加快耗时的第三方 API 请求。
Transients 相关函数
首先说下,Transients 的存储,如果服务器开启了 Memcached,那么缓存的数据就会存在 Memcached 的内存中,如果没有开启的话,则存储到 WordPress 数据库的 Options 表中
所以它的接口函数和 WordPress 的 Option API (get_option
, add_option
, update_option
, delete_option
))基本一样,唯一区别就是 Transients API 有一个过期时间,并且它没有 add 方法,统一合并成 set 了,所以 WordPress Transients API 有以下三个函数:
// 保存一个数据到短时缓存中
set_transient( string $transient, mixed $value, int $expiration )
// 从短时缓存中获取一个数据
get_transient( string $transient )
// 从短时缓存中删除一个数据
delete_transient( string $transient )
函数的使用过非常简单,这里不做详细解释,简单注意下两点:
- 如果使用获取短时缓存函数
get_transient
去获取数据,已经过期或者不存在的情况下是返回 false 的。 - 完全不用担心 Transients API 会将数据库的 Options 表塞满数据,因为临时变量一旦过期,下次获取的时候就会自动被删除,并且上面也说了如果服务器开启了 Memcached,那么缓存的数据就会存在 Memcached 的内存中。
一个应用 Transients 的例子
🙋♀️🌰 假设你要获取博客的浏览最高的 10 篇文章,文章的浏览数据一般是存在 PostMeta 表中,所以这样的数据库查询会用到 Posts 表和 PostMeta 表进行联表查询,如果文章数量比较多的情况下,这样的查询一般是比较慢的。
而事情的另一面,博客浏览最高的 10 篇文章一般来说在一段时间(比如:12小时)之内很可能是不变的,所以这个功能最适合使用 Transients API 进行缓存了:
$top_10_posts = get_transient('top_10_posts');
if(false === $top_10_posts){ // 临时变量过期了或者根本就没有创建
// 通过 SQL 查询获取流量最高的 10 篇文章,
$top_10_posts = wpjam_get_top_viewd_posts(10);
// 把临时变量存到数据库中,时间为 12 个小时
set_transient('top_10_posts', $top_10_posts, HOUR_IN_SECONDS*12);
}
我们首先使用 get_transient('top_10_posts')
函数从缓存中看看有没有缓存,如果没有,该函数是返回 false
的。
程序获取缓存结果为 false 的时候,就通过 wpjam_get_top_viewd_posts
这个带有复杂 SQL 的函数获取文章,然后通过函数 set_transient('top_10_posts', $top_10_posts, HOUR_IN_SECONDS*12)
存到缓存中,并且过期时间设置为 12 小时。
这样下次再去获取浏览最高的文章,直接从缓存中返回了,就不用担心不用担心数据库查询过慢的问题了。
使用 Hook 删除短时缓存
如果由于某种原因某篇流行文章删除,这个时候可能流量最高的文章都可能发生变化,我们就可以使用 delete_transient
函数把这个临时变量删除了,这样我们可以使用 WordPress 的删除文章的 Hook delete_post
进行操作:
add_action('delete_post', fn() => delete_transient('top_10_posts'));
如果你想有新文章发布了,虽然这时候一般不会影响浏览最高的文章列表,但是如果想,也可以把缓存清理了,这时候用到是 publish_post
Hook:
add_action('publish_post', fn() => delete_transient('top_10_posts'));