概述
本页包含WordPress 临时缓存 API(Transients API)的技术文档,它提供了一种简单且标准化的方式,通过为数据指定自定义名称和过期时间,在数据库中临时存储缓存数据。
临时缓存 API 与选项 API(Options API)非常相似,但增加了过期时间的功能,从而简化了使用wp_options数据库表临时存储缓存信息的过程。
请注意,“site_"函数与其对应函数本质上相同,但在 WordPress 多站点(Multisite)环境下,它们会在整个网络范围内运行。
另外需要注意的是,临时缓存会因缓存插件而自动加速,而普通选项则不会。例如,一个memcached插件会使 WordPress 将临时缓存值存储在快速内存中,而不是数据库中。因此,临时缓存应用于存储预期会过期或随时可能过期的任何数据。此外,不应假设临时缓存一定存在于数据库中,因为它们可能根本未被存储在那里。
此外,临时缓存可能在过期时间之前就无法获取。就像缓存处理一样,您的代码应包含一种回退方法,以便在临时缓存不可用时重新生成数据。
Ryan McCue 曾在工单中这样解释:
似乎大家都误解了临时缓存过期的工作原理,简而言之:临时缓存的过期时间是最大时限。没有最小年龄限制。临时缓存可能在设置后一秒钟就消失,也可能存在 24 小时,但它们绝不会在过期时间之后仍然存在。
本文的目标读者包括 WordPress 主题作者、插件作者以及需要缓存特定数据但希望其在给定时间内刷新的任何人。本文假定读者具备基本的 PHP 脚本知识。
函数参考
设置/获取临时缓存:
删除临时缓存:
使用临时缓存
保存临时缓存
要保存临时缓存,请使用set_transient():
set_transient( $transient, $value, $expiration );$transient(字符串):临时缓存名称。
不应进行 SQL 转义。长度必须为 172 个字符或更少。$value(数组/对象):要保存的数据,可以是普通变量或数组/对象。
API 将为您处理复杂数据的序列化。$expiration(整数):刷新前保留数据的最大秒数。
临时缓存可能会在$expiration之前过期(由于外部对象缓存或数据库升级),但绝不会在超过$expiration 后返回其值。
例如,若要保存$special_query_results对象 12 小时,您可以这样做:
set_transient( 'special_query_results', $special_query_results, 60*60*12 );使用时间常量
在WordPress 3.5中,引入了几个常量以方便表示时间:
MINUTE_IN_SECONDS = 60 (seconds)
HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS
DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS
WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS
MONTH_IN_SECONDS = 30 * DAY_IN_SECONDS
YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS因此,上述代码示例可以简化为:
set_transient( 'special_query_results', $special_query_results, 12 * HOUR_IN_SECONDS );获取临时缓存
要获取已保存的临时缓存,请使用get_transient():
get_transient( $transient );$transient:在使用set_transient()保存临时缓存时使用的唯一标识符。
在我们的案例中,我们可以这样获取特殊查询结果:
get_transient( 'special_query_results' );如果临时缓存不存在或已过期,get_transient()将返回false。应使用恒等运算符===而非普通相等运算符==进行检查,因为整数值零(或其他“空”/“假”数据)可能是您想要存储的数据。正因为这个“false"值,临时缓存不应用于存储纯布尔值(true/false)。请将其放入数组或转换为整数。
使用示例:
if ( false === ( $value = get_transient( 'value' ) ) ) {
// 当没有有效的临时缓存设置时运行此代码
}上述代码将获取临时缓存并将其放入$value中。if 块内的代码仅在无法获取有效临时缓存时运行。这通常是通过其他手段重新生成临时缓存值的方法。请记住,临时缓存可能在正常过期时间之前就不可用。
移除已保存的临时缓存
在我们最后一次运行set_transient()后,一旦经过$expiration 秒,我们的临时缓存就会自然过期。但我们也可以通过手动删除强制临时缓存提前失效。这在某些活动(如保存文章、添加分类法等)会导致缓存数据天然过时并需要更新时非常有用。
delete_transient( $transient );$transient:在使用set_transient()保存时使用的唯一名称。
在我们的案例中,显然是:
delete_transient( 'special_query_results' );WordPress 很少清理过期的临时缓存。为了防止过期临时缓存堆积在数据库中,最好的做法是在完成使用且不再需要临时缓存时始终将其删除。
完整示例
将所有内容整合在一起,这里有一个如何在代码中使用临时缓存的示例。
<?php
// 获取现有的临时缓存数据副本
if ( false === ( $special_query_results = get_transient( 'special_query_results' ) ) ) {
// 如果没有,则重新生成数据并保存临时缓存
$special_query_results = new WP_Query( 'cat=5&order=random&tag=tech&post_meta_key=thumbnail' );
set_transient( 'special_query_results', $special_query_results, 12 * HOUR_IN_SECONDS );
}
// 像往常一样使用这些数据...
?>这是一个使用delete_transient()的示例。在本例中,我们将把一个函数添加到edit_term动作钩子中,该函数将在每次编辑分类或标签时运行(即我们假设编辑术语会使我们的数据失效,并希望移除缓存版本)。
<?php
// 创建一个简单的函数来删除我们的临时缓存
function edit_term_delete_transient() {
delete_transient( 'special_query_results' );
}
// 将该函数添加到 edit_term 钩子,以便在编辑分类/标签时运行
add_action( 'edit_term', 'edit_term_delete_transient' );
?>使用WP_Query配合临时缓存检索“精选文章”:
<?php
// 检查临时缓存。如果没有,则执行 WP_Query
if ( false === ( $featured = get_transient( 'foo_featured_posts' ) ) ) {
$featured = new WP_Query(
array(
'category' => 'featured',
'posts_per_page' => 5
)
);
// 将结果存入临时缓存。12 小时后过期。
set_transient( 'foo_featured_posts', $featured, 12 * HOUR_IN_SECONDS );
}
?>
// 像往常一样运行循环
<?php if ( $featured->have_posts() ) : ?>
<?php while ( $featured->have_posts() ) : $featured->the_post(); ?>
// 找到精选文章,执行操作
<?php endwhile; ?>
<?php else: ?>
// 未找到精选文章
<?php endif; ?>
<?php wp_reset_postdata(); ?>
在插件和主题中使用临时缓存非常简单,仅增加了几行代码,但如果用在合适的场景(耗时较长的数据库查询或复杂的处理数据),它可以节省网站的加载时间。