默认情况下,WordPress执行一种形式的“对象缓存”,但其生存期仅为单页加载。
选项实际上就是一个很好的例子。退房this answer 了解更多信息。总结:
页面开始时,所有选项都会加载一个简单的SELECT option_name, option_value from $wpdb->options
声明对这些选项的后续请求(例如get_option
永远不要访问数据库,因为它们是用WP缓存API存储的选项始终“存在”于数据库中,并始终保存在那里——这是它们的“规范”源。这就是说,选项会加载到对象缓存中,因此当您请求选项时,请求有99%的几率不会命中数据库。
瞬态有点不同。
WordPress允许您将缓存api替换为一个下拉菜单,该文件直接放置在wp-content
文件夹如果您创建自己的缓存拖放或使用existing plugin, 您可以使对象缓存的持续时间长于单个页面加载。当你这样做的时候,瞬变,改变一点。
让我们看看set_transient
中的函数wp-includes/option.php
.
<?php
/**
* Set/update the value of a transient.
*
* You do not need to serialize values. If the value needs to be serialized, then
* it will be serialized before it is set.
*
* @since 2.8.0
* @package WordPress
* @subpackage Transient
*
* @uses apply_filters() Calls \'pre_set_transient_$transient\' hook to allow overwriting the
* transient value to be stored.
* @uses do_action() Calls \'set_transient_$transient\' and \'setted_transient\' hooks on success.
*
* @param string $transient Transient name. Expected to not be SQL-escaped.
* @param mixed $value Transient value. Expected to not be SQL-escaped.
* @param int $expiration Time until expiration in seconds, default 0
* @return bool False if value was not set and true if value was set.
*/
function set_transient( $transient, $value, $expiration = 0 ) {
global $_wp_using_ext_object_cache;
$value = apply_filters( \'pre_set_transient_\' . $transient, $value );
if ( $_wp_using_ext_object_cache ) {
$result = wp_cache_set( $transient, $value, \'transient\', $expiration );
} else {
$transient_timeout = \'_transient_timeout_\' . $transient;
$transient = \'_transient_\' . $transient;
if ( false === get_option( $transient ) ) {
$autoload = \'yes\';
if ( $expiration ) {
$autoload = \'no\';
add_option( $transient_timeout, time() + $expiration, \'\', \'no\' );
}
$result = add_option( $transient, $value, \'\', $autoload );
} else {
if ( $expiration )
update_option( $transient_timeout, time() + $expiration );
$result = update_option( $transient, $value );
}
}
if ( $result ) {
do_action( \'set_transient_\' . $transient );
do_action( \'setted_transient\', $transient );
}
return $result;
}
嗯,嗯
$_wp_using_ext_object_cache
? 如果这是真的,WordPress将使用对象缓存而不是数据库来存储瞬态。那么,这是如何实现的呢?是时候探索一下WP如何设置自己的缓存API了。
你几乎可以追踪到wp-load.php
或wp-settings.php
-- 这两者对WordPress的引导过程都至关重要。在我们的缓存中,有一些相关的行wp-settings.php
.
// Start the WordPress object cache, or an external object cache if the drop-in is present.
wp_start_object_cache();
还记得从上面掉下来的东西吗?让我们看看
wp_start_object_cache
在里面
wp-includes/load.php
.
<?php
/**
* Starts the WordPress object cache.
*
* If an object-cache.php file exists in the wp-content directory,
* it uses that drop-in as an external object cache.
*
* @access private
* @since 3.0.0
*/
function wp_start_object_cache() {
global $_wp_using_ext_object_cache, $blog_id;
$first_init = false;
if ( ! function_exists( \'wp_cache_init\' ) ) {
if ( file_exists( WP_CONTENT_DIR . \'/object-cache.php\' ) ) {
require_once ( WP_CONTENT_DIR . \'/object-cache.php\' );
$_wp_using_ext_object_cache = true;
} else {
require_once ( ABSPATH . WPINC . \'/cache.php\' );
$_wp_using_ext_object_cache = false;
}
$first_init = true;
} else if ( !$_wp_using_ext_object_cache && file_exists( WP_CONTENT_DIR . \'/object-cache.php\' ) ) {
// Sometimes advanced-cache.php can load object-cache.php before it is loaded here.
// This breaks the function_exists check above and can result in $_wp_using_ext_object_cache
// being set incorrectly. Double check if an external cache exists.
$_wp_using_ext_object_cache = true;
}
// If cache supports reset, reset instead of init if already initialized.
// Reset signals to the cache that global IDs have changed and it may need to update keys
// and cleanup caches.
if ( ! $first_init && function_exists( \'wp_cache_switch_to_blog\' ) )
wp_cache_switch_to_blog( $blog_id );
else
wp_cache_init();
if ( function_exists( \'wp_cache_add_global_groups\' ) ) {
wp_cache_add_global_groups( array( \'users\', \'userlogins\', \'usermeta\', \'user_meta\', \'site-transient\', \'site-options\', \'site-lookup\', \'blog-lookup\', \'blog-details\', \'rss\', \'global-posts\', \'blog-id-cache\' ) );
wp_cache_add_non_persistent_groups( array( \'comment\', \'counts\', \'plugins\' ) );
}
}
功能的相关行(与
$_wp_using_ext_object_cache
这会改变瞬态的存储方式)。
if ( file_exists( WP_CONTENT_DIR . \'/object-cache.php\' ) ) {
require_once ( WP_CONTENT_DIR . \'/object-cache.php\' );
$_wp_using_ext_object_cache = true;
} else {
require_once ( ABSPATH . WPINC . \'/cache.php\' );
$_wp_using_ext_object_cache = false;
}
如果
object-cache.php
存在于您的内容目录中,它会被包括在内,WP假设您使用的是外部持久缓存--它设置
$_wp_using_ext_object_cache
为真。
如果您使用的是外部对象缓存,瞬态将使用它。这就提出了何时使用选项与瞬态的问题。
易于理解的如果需要数据无限期地持久化,请使用选项。它们被“缓存”,但它们的规范源是数据库,除非用户明确请求,否则它们永远不会消失。
对于应该存储一定时间,但不需要超过指定寿命的数据,请使用瞬态。在内部,如果可以的话,WP将尝试使用外部持久对象缓存,否则数据将进入选项表并通过WordPress\' psuedo-cron 当它们到期时。
其他一些关注/问题:
打很多电话给get_option
?可能吧。它们会导致调用函数的开销,但可能不会影响数据库。在web应用程序可伸缩性方面,数据库负载通常比您选择的语言生成页面的工作更重要我如何知道使用瞬态与缓存API如果您希望数据在设定的时间段内保持不变,请使用瞬态API。如果数据是否持续存在无关紧要(例如,计算/获取数据不会花费很长时间,但每次页面加载不会发生多次),请使用缓存API所有选项真的缓存在每个页面加载上吗不一定。如果你打电话add_option
最后一个可选参数为no
它们不是自动加载的。也就是说,一旦您提取它们一次,它们就会进入缓存,后续调用不会命中数据库