From edfe2ece51edc40e2bca866b95eb7587966a5851 Mon Sep 17 00:00:00 2001 From: Mark Jaquith Date: Wed, 21 Feb 2018 14:59:30 +0000 Subject: [PATCH] Cache API: Allow external object caches to gracefully degrade to the default object cache. Rework logic for how external object caches are detected, so that if an external cache does not define a `wp_cache_init()`, the built-in object cache will be used. Object caches can now wrap their entire contents in logic checks. So a Redis caching backend could make sure that the `Redis` PHP class is available before defining all the caching functions. And if Redis is not available, the site doesn't break or throw errors or think it is using caching when it isn't. This is particularly useful for doing local development, where you might want to develop on a site without running Memcache or Redis like you are in production. * Accounts for multisite, which may re-initialize the object cache multiple times. * Accounts for object caches that may include `object-cache.php` during `advanced-cache.php` (before WP loads it). Props jtsternberg, markjaquith. Fixes #22661. Built from https://develop.svn.wordpress.org/trunk@42723 git-svn-id: http://core.svn.wordpress.org/trunk@42553 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/load.php | 51 +++++++++++++++++++++++++---------------- wp-includes/version.php | 2 +- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/wp-includes/load.php b/wp-includes/load.php index 704e24472f..9c7053eb14 100644 --- a/wp-includes/load.php +++ b/wp-includes/load.php @@ -530,30 +530,39 @@ function wp_using_ext_object_cache( $using = null ) { */ function wp_start_object_cache() { global $wp_filter; + static $first_init = true; - $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' ); - if ( function_exists( 'wp_cache_init' ) ) { - wp_using_ext_object_cache( true ); - } + // Only perform the following checks once. + if ( $first_init ) { + if ( ! function_exists( 'wp_cache_init' ) ) { + /* + * This is the normal situation. First-run of this function. No + * caching backend has been loaded. + * + * We try to load a custom caching backend, and then, if it + * results in a wp_cache_init() function existing, we note + * that an external object cache is being used. + */ + if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) { + require_once( WP_CONTENT_DIR . '/object-cache.php' ); + if ( function_exists( 'wp_cache_init' ) ) { + wp_using_ext_object_cache( true ); + } - // Re-initialize any hooks added manually by object-cache.php - if ( $wp_filter ) { - $wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter ); + // Re-initialize any hooks added manually by object-cache.php + if ( $wp_filter ) { + $wp_filter = WP_Hook::build_preinitialized_hooks( $wp_filter ); + } } + } elseif ( ! wp_using_ext_object_cache() && file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) { + /* + * Sometimes advanced-cache.php can load object-cache.php before + * this function is run. This breaks the function_exists() check + * above and can result in wp_using_ext_object_cache() returning + * false when actually an external cache is in use. + */ + wp_using_ext_object_cache( true ); } - - $first_init = true; - } elseif ( ! 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 ( ! wp_using_ext_object_cache() ) { @@ -575,6 +584,8 @@ function wp_start_object_cache() { wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'useremail', 'userslugs', 'site-transient', 'site-options', 'blog-lookup', 'blog-details', 'site-details', 'rss', 'global-posts', 'blog-id-cache', 'networks', 'sites' ) ); wp_cache_add_non_persistent_groups( array( 'counts', 'plugins' ) ); } + + $first_init = false; } /** diff --git a/wp-includes/version.php b/wp-includes/version.php index 0a0b803cdc..e014e6fe39 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '5.0-alpha-42722'; +$wp_version = '5.0-alpha-42723'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.