函数文档

wp_prime_option_caches()

💡 云策文档标注

概述

wp_prime_option_caches() 函数用于通过单次数据库查询将指定选项预加载到缓存中,以提高性能。它仅加载缓存中不存在的选项,并处理未找到选项的缓存更新。

关键要点

  • 函数通过单次数据库查询预加载选项到缓存,减少数据库访问次数
  • 仅处理缓存中不存在的选项,避免重复加载
  • 使用 wp_cache_set_multiple() 和 wp_cache_get_multiple() 进行批量缓存操作
  • 维护 notoptions 缓存以记录不存在的选项,优化后续查询
  • 函数在 WordPress 6.4.0 版本中引入

代码示例

function wp_prime_option_caches( $options ) {
    global $wpdb;

    $alloptions     = wp_load_alloptions();
    $cached_options = wp_cache_get_multiple( $options, 'options' );
    $notoptions     = wp_cache_get( 'notoptions', 'options' );
    if ( ! is_array( $notoptions ) ) {
        $notoptions = array();
    }

    // Filter options that are not in the cache.
    $options_to_prime = array();
    foreach ( $options as $option ) {
        if (
            ( ! isset( $cached_options[ $option ] ) || false === $cached_options[ $option ] )
            && ! isset( $alloptions[ $option ] )
            && ! isset( $notoptions[ $option ] )
        ) {
            $options_to_prime[] = $option;
        }
    }

    // Bail early if there are no options to be loaded.
    if ( empty( $options_to_prime ) ) {
        return;
    }

    $results = $wpdb->get_results(
        $wpdb->prepare(
            sprintf(
                "SELECT option_name, option_value FROM $wpdb->options WHERE option_name IN (%s)",
                implode( ',', array_fill( 0, count( $options_to_prime ), '%s' ) )
            ),
            $options_to_prime
        )
    );

    $options_found = array();
    foreach ( $results as $result ) {
        /*
         * The cache is primed with the raw value (i.e. not maybe_unserialized).
         *
         * `get_option()` will handle unserializing the value as needed.
         */
        $options_found[ $result->option_name ] = $result->option_value;
    }
    wp_cache_set_multiple( $options_found, 'options' );

    // If all options were found, no need to update `notoptions` cache.
    if ( count( $options_found ) === count( $options_to_prime ) ) {
        return;
    }

    $options_not_found = array_diff( $options_to_prime, array_keys( $options_found ) );

    // Add the options that were not found to the cache.
    $update_notoptions = false;
    foreach ( $options_not_found as $option_name ) {
        if ( ! isset( $notoptions[ $option_name ] ) ) {
            $notoptions[ $option_name ] = true;
            $update_notoptions          = true;
        }
    }

    // Only update the cache if it was modified.
    if ( $update_notoptions ) {
        wp_cache_set( 'notoptions', $notoptions, 'options' );
    }
}

注意事项

  • 函数仅加载缓存中不存在的选项,已缓存或标记为不存在的选项会被跳过
  • 缓存使用原始值(未反序列化),get_option() 会在需要时处理反序列化
  • 如果所有选项都找到,则不会更新 notoptions 缓存
  • 函数依赖于 wpdb 类进行数据库查询,确保数据库连接正常

📄 原文内容

Primes specific options into the cache with a single database query.

Description

Only options that do not already exist in cache will be loaded.

Parameters

$optionsstring[]required
An array of option names to be loaded.

Source

function wp_prime_option_caches( $options ) {
	global $wpdb;

	$alloptions     = wp_load_alloptions();
	$cached_options = wp_cache_get_multiple( $options, 'options' );
	$notoptions     = wp_cache_get( 'notoptions', 'options' );
	if ( ! is_array( $notoptions ) ) {
		$notoptions = array();
	}

	// Filter options that are not in the cache.
	$options_to_prime = array();
	foreach ( $options as $option ) {
		if (
			( ! isset( $cached_options[ $option ] ) || false === $cached_options[ $option ] )
			&& ! isset( $alloptions[ $option ] )
			&& ! isset( $notoptions[ $option ] )
		) {
			$options_to_prime[] = $option;
		}
	}

	// Bail early if there are no options to be loaded.
	if ( empty( $options_to_prime ) ) {
		return;
	}

	$results = $wpdb->get_results(
		$wpdb->prepare(
			sprintf(
				"SELECT option_name, option_value FROM $wpdb->options WHERE option_name IN (%s)",
				implode( ',', array_fill( 0, count( $options_to_prime ), '%s' ) )
			),
			$options_to_prime
		)
	);

	$options_found = array();
	foreach ( $results as $result ) {
		/*
		 * The cache is primed with the raw value (i.e. not maybe_unserialized).
		 *
		 * `get_option()` will handle unserializing the value as needed.
		 */
		$options_found[ $result->option_name ] = $result->option_value;
	}
	wp_cache_set_multiple( $options_found, 'options' );

	// If all options were found, no need to update `notoptions` cache.
	if ( count( $options_found ) === count( $options_to_prime ) ) {
		return;
	}

	$options_not_found = array_diff( $options_to_prime, array_keys( $options_found ) );

	// Add the options that were not found to the cache.
	$update_notoptions = false;
	foreach ( $options_not_found as $option_name ) {
		if ( ! isset( $notoptions[ $option_name ] ) ) {
			$notoptions[ $option_name ] = true;
			$update_notoptions          = true;
		}
	}

	// Only update the cache if it was modified.
	if ( $update_notoptions ) {
		wp_cache_set( 'notoptions', $notoptions, 'options' );
	}
}

Changelog

Version Description
6.4.0 Introduced.