wp_set_option_autoload_values

函数
wp_set_option_autoload_values ( $options )
参数
  • (array) $options Associative array of option names and their autoload values to set. The option names are expected to not be SQL-escaped. The autoload values accept 'yes'|true to enable or 'no'|false to disable.
    Required:
返回值
  • (array) Associative array of all provided $options as keys and boolean values for whether their autoload value was updated.
定义位置
相关方法
wp_set_option_autoloadwp_set_options_autoloadget_post_custom_valuesis_user_option_localwp_prime_option_caches
引入
6.4.0
弃用
-

设置数据库中多个选项的自动加载值。

自动加载过多的选项会导致性能问题,尤其是在选项不常用的情况下。该函数允许修改多个选项的自动加载值,而无需更改实际选项值。例如,建议在插件激活和停用钩子时使用此功能,以确保插件专用的、通常自动加载的选项可以设置为在插件停用时不自动加载。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function wp_set_option_autoload_values( array $options ) {
global $wpdb;
if ( ! $options ) {
return array();
}
$grouped_options = array(
'yes' => array(),
'no' => array(),
);
$results = array();
foreach ( $options as $option => $autoload ) {
wp_protect_special_option( $option ); // Ensure only valid options can be passed.
if ( 'no' === $autoload || false === $autoload ) { // Sanitize autoload value and categorize accordingly.
$grouped_options['no'][] = $option;
} else {
$grouped_options['yes'][] = $option;
}
$results[ $option ] = false; // Initialize result value.
}
$where = array();
$where_args = array();
foreach ( $grouped_options as $autoload => $options ) {
if ( ! $options ) {
continue;
}
$placeholders = implode( ',', array_fill( 0, count( $options ), '%s' ) );
$where[] = "autoload != '%s' AND option_name IN ($placeholders)";
$where_args[] = $autoload;
foreach ( $options as $option ) {
$where_args[] = $option;
}
}
$where = 'WHERE ' . implode( ' OR ', $where );
/*
* Determine the relevant options that do not already use the given autoload value.
* If no options are returned, no need to update.
*/
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
$options_to_update = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->options $where", $where_args ) );
if ( ! $options_to_update ) {
return $results;
}
// Run UPDATE queries as needed (maximum 2) to update the relevant options' autoload values to 'yes' or 'no'.
foreach ( $grouped_options as $autoload => $options ) {
if ( ! $options ) {
continue;
}
$options = array_intersect( $options, $options_to_update );
$grouped_options[ $autoload ] = $options;
if ( ! $grouped_options[ $autoload ] ) {
continue;
}
// Run query to update autoload value for all the options where it is needed.
$success = $wpdb->query(
$wpdb->prepare(
"UPDATE $wpdb->options SET autoload = %s WHERE option_name IN (" . implode( ',', array_fill( 0, count( $grouped_options[ $autoload ] ), '%s' ) ) . ')',
array_merge(
array( $autoload ),
$grouped_options[ $autoload ]
)
)
);
if ( ! $success ) {
// Set option list to an empty array to indicate no options were updated.
$grouped_options[ $autoload ] = array();
continue;
}
// Assume that on success all options were updated, which should be the case given only new values are sent.
foreach ( $grouped_options[ $autoload ] as $option ) {
$results[ $option ] = true;
}
}
/*
* If any options were changed to 'yes', delete their individual caches, and delete 'alloptions' cache so that it
* is refreshed as needed.
* If no options were changed to 'yes' but any options were changed to 'no', delete them from the 'alloptions'
* cache. This is not necessary when options were changed to 'yes', since in that situation the entire cache is
* deleted anyway.
*/
if ( $grouped_options['yes'] ) {
wp_cache_delete_multiple( $grouped_options['yes'], 'options' );
wp_cache_delete( 'alloptions', 'options' );
} elseif ( $grouped_options['no'] ) {
$alloptions = wp_load_alloptions( true );
foreach ( $grouped_options['no'] as $option ) {
if ( isset( $alloptions[ $option ] ) ) {
unset( $alloptions[ $option ] );
}
}
wp_cache_set( 'alloptions', $alloptions, 'options' );
}
return $results;
}
function wp_set_option_autoload_values( array $options ) { global $wpdb; if ( ! $options ) { return array(); } $grouped_options = array( 'yes' => array(), 'no' => array(), ); $results = array(); foreach ( $options as $option => $autoload ) { wp_protect_special_option( $option ); // Ensure only valid options can be passed. if ( 'no' === $autoload || false === $autoload ) { // Sanitize autoload value and categorize accordingly. $grouped_options['no'][] = $option; } else { $grouped_options['yes'][] = $option; } $results[ $option ] = false; // Initialize result value. } $where = array(); $where_args = array(); foreach ( $grouped_options as $autoload => $options ) { if ( ! $options ) { continue; } $placeholders = implode( ',', array_fill( 0, count( $options ), '%s' ) ); $where[] = "autoload != '%s' AND option_name IN ($placeholders)"; $where_args[] = $autoload; foreach ( $options as $option ) { $where_args[] = $option; } } $where = 'WHERE ' . implode( ' OR ', $where ); /* * Determine the relevant options that do not already use the given autoload value. * If no options are returned, no need to update. */ // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare $options_to_update = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->options $where", $where_args ) ); if ( ! $options_to_update ) { return $results; } // Run UPDATE queries as needed (maximum 2) to update the relevant options' autoload values to 'yes' or 'no'. foreach ( $grouped_options as $autoload => $options ) { if ( ! $options ) { continue; } $options = array_intersect( $options, $options_to_update ); $grouped_options[ $autoload ] = $options; if ( ! $grouped_options[ $autoload ] ) { continue; } // Run query to update autoload value for all the options where it is needed. $success = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->options SET autoload = %s WHERE option_name IN (" . implode( ',', array_fill( 0, count( $grouped_options[ $autoload ] ), '%s' ) ) . ')', array_merge( array( $autoload ), $grouped_options[ $autoload ] ) ) ); if ( ! $success ) { // Set option list to an empty array to indicate no options were updated. $grouped_options[ $autoload ] = array(); continue; } // Assume that on success all options were updated, which should be the case given only new values are sent. foreach ( $grouped_options[ $autoload ] as $option ) { $results[ $option ] = true; } } /* * If any options were changed to 'yes', delete their individual caches, and delete 'alloptions' cache so that it * is refreshed as needed. * If no options were changed to 'yes' but any options were changed to 'no', delete them from the 'alloptions' * cache. This is not necessary when options were changed to 'yes', since in that situation the entire cache is * deleted anyway. */ if ( $grouped_options['yes'] ) { wp_cache_delete_multiple( $grouped_options['yes'], 'options' ); wp_cache_delete( 'alloptions', 'options' ); } elseif ( $grouped_options['no'] ) { $alloptions = wp_load_alloptions( true ); foreach ( $grouped_options['no'] as $option ) { if ( isset( $alloptions[ $option ] ) ) { unset( $alloptions[ $option ] ); } } wp_cache_set( 'alloptions', $alloptions, 'options' ); } return $results; }
function wp_set_option_autoload_values( array $options ) {
	global $wpdb;

	if ( ! $options ) {
		return array();
	}

	$grouped_options = array(
		'yes' => array(),
		'no'  => array(),
	);
	$results         = array();
	foreach ( $options as $option => $autoload ) {
		wp_protect_special_option( $option ); // Ensure only valid options can be passed.
		if ( 'no' === $autoload || false === $autoload ) { // Sanitize autoload value and categorize accordingly.
			$grouped_options['no'][] = $option;
		} else {
			$grouped_options['yes'][] = $option;
		}
		$results[ $option ] = false; // Initialize result value.
	}

	$where      = array();
	$where_args = array();
	foreach ( $grouped_options as $autoload => $options ) {
		if ( ! $options ) {
			continue;
		}
		$placeholders = implode( ',', array_fill( 0, count( $options ), '%s' ) );
		$where[]      = "autoload != '%s' AND option_name IN ($placeholders)";
		$where_args[] = $autoload;
		foreach ( $options as $option ) {
			$where_args[] = $option;
		}
	}
	$where = 'WHERE ' . implode( ' OR ', $where );

	/*
	 * Determine the relevant options that do not already use the given autoload value.
	 * If no options are returned, no need to update.
	 */
	// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
	$options_to_update = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->options $where", $where_args ) );
	if ( ! $options_to_update ) {
		return $results;
	}

	// Run UPDATE queries as needed (maximum 2) to update the relevant options' autoload values to 'yes' or 'no'.
	foreach ( $grouped_options as $autoload => $options ) {
		if ( ! $options ) {
			continue;
		}
		$options                      = array_intersect( $options, $options_to_update );
		$grouped_options[ $autoload ] = $options;
		if ( ! $grouped_options[ $autoload ] ) {
			continue;
		}

		// Run query to update autoload value for all the options where it is needed.
		$success = $wpdb->query(
			$wpdb->prepare(
				"UPDATE $wpdb->options SET autoload = %s WHERE option_name IN (" . implode( ',', array_fill( 0, count( $grouped_options[ $autoload ] ), '%s' ) ) . ')',
				array_merge(
					array( $autoload ),
					$grouped_options[ $autoload ]
				)
			)
		);
		if ( ! $success ) {
			// Set option list to an empty array to indicate no options were updated.
			$grouped_options[ $autoload ] = array();
			continue;
		}

		// Assume that on success all options were updated, which should be the case given only new values are sent.
		foreach ( $grouped_options[ $autoload ] as $option ) {
			$results[ $option ] = true;
		}
	}

	/*
	 * If any options were changed to 'yes', delete their individual caches, and delete 'alloptions' cache so that it
	 * is refreshed as needed.
	 * If no options were changed to 'yes' but any options were changed to 'no', delete them from the 'alloptions'
	 * cache. This is not necessary when options were changed to 'yes', since in that situation the entire cache is
	 * deleted anyway.
	 */
	if ( $grouped_options['yes'] ) {
		wp_cache_delete_multiple( $grouped_options['yes'], 'options' );
		wp_cache_delete( 'alloptions', 'options' );
	} elseif ( $grouped_options['no'] ) {
		$alloptions = wp_load_alloptions( true );

		foreach ( $grouped_options['no'] as $option ) {
			if ( isset( $alloptions[ $option ] ) ) {
				unset( $alloptions[ $option ] );
			}
		}

		wp_cache_set( 'alloptions', $alloptions, 'options' );
	}

	return $results;
}

常见问题

FAQs
查看更多 >