各位听众,早上好/下午好/晚上好! 今天咱们来聊聊 WordPress 的“小秘密”——get_transient()
函数。别看它名字平平无奇,实际上它可是 WordPress 缓存机制中的一位重要成员。它能让你在数据库里“偷偷”存放一些临时数据,就像在冰箱里放个冰淇淋,过会儿拿出来吃,省得每次都现做。
咱们今天要深入它的源码,看看它到底是怎么运作的,又是如何跟 wp_options
表,以及那个让人又爱又恨的“过期时间”打交道的。准备好了吗? Let’s dive in!
1. Transient 究竟是啥?
首先,咱们得明白什么是 Transient。简单来说,Transient 就是一个临时的缓存数据,它有一个过期时间,过了这个时间,数据就会自动失效。想象一下,你用积分换购了一张电影票,这张票在有效期内有效,过了期就作废了。Transient 的作用就类似这样。
为什么要用 Transient 呢? 主要是为了减轻数据库的压力,提高网站的性能。 比如,你要显示一个热门文章列表,每次都去数据库里查询,效率肯定不高。但如果把热门文章列表缓存成一个 Transient,隔一段时间更新一次,就能大大提高速度。
2. get_transient()
函数:寻宝之旅的开始
get_transient()
函数是用来获取 Transient 值的。 它的基本用法是:
$value = get_transient( 'my_transient_key' );
if ( false === $value ) {
// Transient 不存在或者已过期,重新计算值
$value = calculate_expensive_value();
// 设置 Transient,有效期为 1 小时 (3600 秒)
set_transient( 'my_transient_key', $value, 3600 );
}
// 现在 $value 就是我们要用的值了
echo $value;
这段代码做了什么呢?
- 首先,它尝试从 Transient 里获取
my_transient_key
对应的值。 - 如果
get_transient()
返回false
,说明 Transient 不存在或者已经过期了,需要重新计算值。 - 重新计算后,用
set_transient()
函数设置 Transient,并设置过期时间为 1 小时。 - 最后,就可以使用 Transient 的值了。
那么,get_transient()
到底是怎么找到这个值的呢? 让我们一起深入源码看看。
3. get_transient()
源码剖析:深入 wp-includes/option.php
打开 wp-includes/option.php
文件,找到 get_transient()
函数。 它的源码大致如下:
function get_transient( $transient ) {
/**
* Fires before a cached transient is retrieved.
*
* The dynamic portion of the hook name, `$transient`, refers to the transient name.
*
* @since 2.8.0
*
* @param string $transient Transient name.
*/
do_action( 'pre_get_transient_' . $transient );
$pre = apply_filters( 'pre_transient_' . $transient, false );
if ( false !== $pre ) {
return $pre;
}
$transient_option = _transient_key( $transient );
$transient_timeout = _transient_timeout_key( $transient );
$timeout = get_option( $transient_timeout );
if ( false !== $timeout && time() > intval( $timeout ) ) {
delete_transient( $transient );
return false;
}
$value = get_option( $transient_option );
/**
* Filters an existing transient value to be returned.
*
* The dynamic portion of the hook name, `$transient`, refers to the transient name.
*
* @since 2.8.0
*
* @param mixed $value Value of transient.
* @param string $transient Transient name.
*/
return apply_filters( 'transient_' . $transient, $value, $transient );
}
哇,看起来有点复杂,别怕,咱们一步一步来分析。
-
Hook 机制:
do_action()
和apply_filters()
首先,我们看到
do_action( 'pre_get_transient_' . $transient );
和apply_filters( 'pre_transient_' . $transient, false );
这两行代码。 这是 WordPress 的 Hook 机制,允许我们在 Transient 被获取之前,执行一些自定义的操作。do_action()
允许我们执行一些操作,但不返回任何值。 比如,我们可以在 Transient 被获取之前,记录一条日志。apply_filters()
允许我们修改 Transient 的值。 如果apply_filters()
返回的值不是false
,那么get_transient()
函数就会直接返回这个值,而不会继续往下执行。 这提供了一种非常灵活的方式来控制 Transient 的获取过程。 -
生成 Option Key:
_transient_key()
和_transient_timeout_key()
接下来,我们看到:
$transient_option = _transient_key( $transient ); $transient_timeout = _transient_timeout_key( $transient );
这两个函数分别生成了 Transient 的 Option Key 和 Timeout Key。 它们的作用是把 Transient 的名字转换成在
wp_options
表中存储的 key。让我们看看这两个函数的源码:
function _transient_key( $transient ) { return '_transient_' . $transient; } function _transient_timeout_key( $transient ) { return '_transient_timeout_' . $transient; }
很简单,它们只是在 Transient 的名字前面加上了
_transient_
和_transient_timeout_
前缀。 比如,如果 Transient 的名字是my_transient_key
,那么 Option Key 就是_transient_my_transient_key
,Timeout Key 就是_transient_timeout_my_transient_key
。 -
获取 Timeout 值:
get_option()
然后,我们看到:
$timeout = get_option( $transient_timeout );
这里使用
get_option()
函数从wp_options
表中获取 Timeout 值。get_option()
是 WordPress 提供的一个非常重要的函数,它可以从wp_options
表中获取 Option 的值。wp_options
表是 WordPress 用来存储各种设置和数据的表格。 它有两个重要的字段:option_name
和option_value
。option_name
存储 Option 的名字,option_value
存储 Option 的值。所以,
get_option( $transient_timeout )
实际上就是从wp_options
表中查找option_name
等于$transient_timeout
的记录,并返回对应的option_value
。 -
检查是否过期:
time() > intval( $timeout )
接下来,我们看到:
if ( false !== $timeout && time() > intval( $timeout ) ) { delete_transient( $transient ); return false; }
这里检查 Transient 是否已经过期。 首先,判断
$timeout
是否为false
。 如果$timeout
为false
,说明这个 Transient 还没有设置 Timeout 值,也就是没有设置过期时间,那么就认为它没有过期。如果
$timeout
不为false
,那么就判断当前时间是否大于 Timeout 值。 如果当前时间大于 Timeout 值,说明 Transient 已经过期了,需要调用delete_transient()
函数删除 Transient,并返回false
。time()
函数返回当前的时间戳,intval()
函数把 Timeout 值转换成整数。 -
获取 Transient 值:
get_option()
如果 Transient 没有过期,那么就执行:
$value = get_option( $transient_option );
这里再次使用
get_option()
函数从wp_options
表中获取 Transient 的值。 这次获取的是 Option Key 对应的值,也就是 Transient 的实际数据。 -
Hook 机制:
apply_filters()
最后,我们看到:
return apply_filters( 'transient_' . $transient, $value, $transient );
这里又使用了一次
apply_filters()
函数。 这次的 Hook 是transient_
+ Transient 的名字。 这个 Hook 允许我们在 Transient 的值被返回之前,修改它的值。这又提供了一种非常灵活的方式来控制 Transient 的返回值。
4. set_transient()
函数:把冰淇淋放进冰箱
现在,我们已经知道了 get_transient()
函数是如何获取 Transient 的值的。 接下来,让我们看看 set_transient()
函数是如何设置 Transient 的值的。
set_transient()
函数的基本用法是:
set_transient( 'my_transient_key', $value, 3600 );
这段代码做了什么呢?
- 它把
$value
存储到my_transient_key
对应的 Transient 中。 - 设置过期时间为 3600 秒,也就是 1 小时。
让我们深入源码看看 set_transient()
函数是如何实现的。
打开 wp-includes/option.php
文件,找到 set_transient()
函数。 它的源码大致如下:
function set_transient( $transient, $value, $expiration = 0 ) {
/**
* Fires before a cached transient is set.
*
* The dynamic portion of the hook name, `$transient`, refers to the transient name.
*
* @since 2.8.0
*
* @param string $transient Transient name.
* @param mixed $value Transient value.
* @param int $expiration Time until expiration in seconds.
*/
do_action( 'set_transient_' . $transient, $value, $expiration );
$transient_timeout = _transient_timeout_key( $transient );
$transient = _transient_key( $transient );
if ( false === get_option( $transient ) ) {
$autoload = 'yes';
if ( is_int( $expiration ) && $expiration ) {
$autoload = 'no';
add_option( $transient_timeout, time() + $expiration, '', $autoload );
}
$result = add_option( $transient, $value, '', $autoload );
if ( $autoload == 'no' ) {
wp_cache_add( $transient_timeout, time() + $expiration, 'options', $expiration );
}
} else {
if ( is_int( $expiration ) && $expiration ) {
update_option( $transient_timeout, time() + $expiration );
} else {
delete_option( $transient_timeout );
}
$result = update_option( $transient, $value );
}
if ( $result ) {
wp_cache_set( $transient, $value, 'options', $expiration );
}
/**
* Fires after a transient is set.
*
* The dynamic portion of the hook name, `$transient`, refers to the transient name.
*
* @since 2.8.0
*
* @param string $transient Transient name.
* @param mixed $value Transient value.
* @param int $expiration Time until expiration in seconds.
*/
do_action( 'setted_transient_' . $transient, $value, $expiration );
return $result;
}
同样,咱们一步一步来分析。
-
Hook 机制:
do_action()
首先,我们看到
do_action( 'set_transient_' . $transient, $value, $expiration );
这行代码。 这是 WordPress 的 Hook 机制,允许我们在 Transient 被设置之前,执行一些自定义的操作。 -
生成 Option Key:
_transient_key()
和_transient_timeout_key()
接下来,我们看到:
$transient_timeout = _transient_timeout_key( $transient ); $transient = _transient_key( $transient );
这两个函数的作用和
get_transient()
函数里的一样,都是用来生成 Transient 的 Option Key 和 Timeout Key。 -
判断 Transient 是否存在:
get_option()
然后,我们看到:
if ( false === get_option( $transient ) ) { // Transient 不存在 } else { // Transient 存在 }
这里使用
get_option()
函数判断 Transient 是否已经存在。 如果get_option()
返回false
,说明 Transient 不存在,需要使用add_option()
函数添加 Transient。 否则,说明 Transient 已经存在,需要使用update_option()
函数更新 Transient。 -
添加 Transient:
add_option()
如果 Transient 不存在,那么就执行:
$autoload = 'yes'; if ( is_int( $expiration ) && $expiration ) { $autoload = 'no'; add_option( $transient_timeout, time() + $expiration, '', $autoload ); } $result = add_option( $transient, $value, '', $autoload ); if ( $autoload == 'no' ) { wp_cache_add( $transient_timeout, time() + $expiration, 'options', $expiration ); }
这里使用
add_option()
函数添加 Transient。add_option()
函数的作用是在wp_options
表中添加一条新的记录。 它有四个参数:$option_name
:Option 的名字。$option_value
:Option 的值。$deprecated
:已弃用的参数,可以忽略。$autoload
:是否自动加载。
$autoload
参数控制着这个 Option 是否在 WordPress 启动时自动加载。 如果$autoload
设置为'yes'
,那么这个 Option 会在 WordPress 启动时自动加载,这会提高性能。 但是,如果 Option 的值很大,或者很少使用,那么就不应该自动加载,应该把$autoload
设置为'no'
。在这里,我们首先判断是否设置了过期时间。 如果设置了过期时间,就把
$autoload
设置为'no'
,并使用add_option()
函数添加 Timeout 值。 然后,使用add_option()
函数添加 Transient 的值。如果
$autoload
是no
,则使用wp_cache_add
将超时时间添加到对象缓存中,有效期与 transient 相同。 -
更新 Transient:
update_option()
如果 Transient 已经存在,那么就执行:
if ( is_int( $expiration ) && $expiration ) { update_option( $transient_timeout, time() + $expiration ); } else { delete_option( $transient_timeout ); } $result = update_option( $transient, $value );
这里使用
update_option()
函数更新 Transient。update_option()
函数的作用是更新wp_options
表中已有的记录。 它有两个参数:$option_name
:Option 的名字。$option_value
:Option 的值。
在这里,我们首先判断是否设置了过期时间。 如果设置了过期时间,就使用
update_option()
函数更新 Timeout 值。 否则,就使用delete_option()
删除 timeout option。 然后,使用update_option()
函数更新 Transient 的值。 -
对象缓存:
wp_cache_set()
最后,我们看到:
if ( $result ) { wp_cache_set( $transient, $value, 'options', $expiration ); }
如果
add_option()
或update_option()
函数执行成功,那么就使用wp_cache_set()
函数把 Transient 的值添加到对象缓存中。对象缓存是 WordPress 提供的一种更高级的缓存机制。 它可以把数据存储到内存中,从而大大提高性能。
wp_cache_set()
函数的作用是把数据存储到对象缓存中。 它有四个参数:$key
:缓存的 key。$data
:缓存的数据。$group
:缓存的组。$expire
:过期时间。
在这里,我们把 Transient 的名字作为缓存的 key,把 Transient 的值作为缓存的数据,把
'options'
作为缓存的组,把过期时间作为缓存的过期时间。 -
Hook 机制:
do_action()
最后,我们看到
do_action( 'setted_transient_' . $transient, $value, $expiration );
这行代码。 这是 WordPress 的 Hook 机制,允许我们在 Transient 被设置之后,执行一些自定义的操作。
5. delete_transient()
函数:冰淇淋过期了,扔掉!
delete_transient()
函数是用来删除 Transient 的。 它的基本用法是:
delete_transient( 'my_transient_key' );
这段代码会删除 my_transient_key
对应的 Transient。
让我们深入源码看看 delete_transient()
函数是如何实现的。
打开 wp-includes/option.php
文件,找到 delete_transient()
函数。 它的源码大致如下:
function delete_transient( $transient ) {
/**
* Fires before a transient is deleted.
*
* The dynamic portion of the hook name, `$transient`, refers to the transient name.
*
* @since 2.8.0
*
* @param string $transient Transient name.
*/
do_action( 'delete_transient_' . $transient );
$transient_timeout = _transient_timeout_key( $transient );
$transient = _transient_key( $transient );
$result = delete_option( $transient );
if ( $result ) {
delete_option( $transient_timeout );
wp_cache_delete( $transient, 'options' );
}
/**
* Fires after a transient is deleted.
*
* The dynamic portion of the hook name, `$transient`, refers to the transient name.
*
* @since 2.8.0
*
* @param string $transient Transient name.
*/
do_action( 'deleted_transient_' . $transient );
return $result;
}
这次的源码比较简单,我们直接分析。
-
Hook 机制:
do_action()
首先,我们看到
do_action( 'delete_transient_' . $transient );
这行代码。 这是 WordPress 的 Hook 机制,允许我们在 Transient 被删除之前,执行一些自定义的操作。 -
生成 Option Key:
_transient_key()
和_transient_timeout_key()
接下来,我们看到:
$transient_timeout = _transient_timeout_key( $transient ); $transient = _transient_key( $transient );
这两个函数的作用和
get_transient()
函数里的一样,都是用来生成 Transient 的 Option Key 和 Timeout Key。 -
删除 Transient:
delete_option()
然后,我们看到:
$result = delete_option( $transient );
这里使用
delete_option()
函数删除 Transient。delete_option()
函数的作用是从wp_options
表中删除一条记录。 它的参数是 Option 的名字。 -
删除 Timeout 值:
delete_option()
接下来,我们看到:
if ( $result ) { delete_option( $transient_timeout ); wp_cache_delete( $transient, 'options' ); }
如果
delete_option( $transient )
函数执行成功,那么就使用delete_option()
函数删除 Timeout 值,并使用wp_cache_delete()
函数从对象缓存中删除 Transient。 -
Hook 机制:
do_action()
最后,我们看到
do_action( 'deleted_transient_' . $transient );
这行代码。 这是 WordPress 的 Hook 机制,允许我们在 Transient 被删除之后,执行一些自定义的操作。
6. Transient 与 wp_options
表:幕后英雄
现在,我们已经了解了 get_transient()
、set_transient()
和 delete_transient()
函数的源码。 我们可以看到,这三个函数都与 wp_options
表密切相关。
wp_options
表是 WordPress 用来存储各种设置和数据的表格。 Transient 实际上就是把数据存储到 wp_options
表中,并设置一个过期时间。
wp_options
表有两个重要的字段:option_name
和 option_value
。 option_name
存储 Option 的名字,option_value
存储 Option 的值。
当我们使用 set_transient()
函数设置一个 Transient 时,实际上是向 wp_options
表中添加了两条记录:
- 一条记录存储 Transient 的值,
option_name
是_transient_
+ Transient 的名字,option_value
是 Transient 的值。 - 一条记录存储 Transient 的过期时间,
option_name
是_transient_timeout_
+ Transient 的名字,option_value
是过期时间的时间戳。
当我们使用 get_transient()
函数获取一个 Transient 的值时,实际上是从 wp_options
表中查找 option_name
等于 _transient_
+ Transient 的名字的记录,并返回对应的 option_value
。 同时,还会检查 _transient_timeout_
+ Transient 的名字对应的记录是否存在,以及是否已经过期。
当我们使用 delete_transient()
函数删除一个 Transient 时,实际上是从 wp_options
表中删除 option_name
等于 _transient_
+ Transient 的名字和 _transient_timeout_
+ Transient 的名字的两条记录。
可以用表格总结一下:
函数 | 操作 | wp_options 表记录 |
---|---|---|
set_transient() |
设置 Transient 值和过期时间 | 添加/更新两条记录:_transient_{transient_name} (值) 和 _transient_timeout_{transient_name} (过期时间戳) |
get_transient() |
获取 Transient 值,检查是否过期 | 根据 _transient_{transient_name} 获取值,根据 _transient_timeout_{transient_name} 检查是否过期,过期则删除记录 |
delete_transient() |
删除 Transient 值和过期时间 | 删除两条记录:_transient_{transient_name} 和 _transient_timeout_{transient_name} |
7. 总结:Transient 的力量
通过今天的讲座,我们深入了解了 WordPress 的 get_transient()
函数,以及它与 wp_options
表和过期时间的关系。 我们可以看到,Transient 是一种非常强大的缓存机制,它可以帮助我们提高 WordPress 网站的性能。
使用 Transient 的好处包括:
- 减轻数据库压力:减少对数据库的查询次数。
- 提高网站性能:更快地加载页面。
- 灵活性:可以设置过期时间,自动失效。
但是,使用 Transient 也需要注意一些问题:
- 不要存储过大的数据:
wp_options
表不适合存储过大的数据。 - 合理设置过期时间:过期时间太短,缓存效果不明显;过期时间太长,数据可能过时。
- 注意 Transient 的命名:Transient 的名字应该具有唯一性,避免冲突。
希望今天的讲座对大家有所帮助。 感谢各位的聆听!下次再见!