update_option()WP 1.0.0

Updates the value of an option (setting) in the database. Expects an unescaped string.

This function can be used to add new options, instead of add_option(): update_option first checks if the specified option exists, if not, control is passed to add_option(). The option name is sanitized before the option is added to the database.

Before version 4.2, it was not possible to specify the $autoload parameter. This means that the function could not indicate that the added option is private and should not be loaded into memory along with all options. For this, it was necessary to use the add_option() function (see description).

Important! By default, the $autoload parameter is set to yes for new options. That is, when normally adding an option through this function, its value will be automatically loaded into memory. In some cases, this can lead to memory overload, so if the option is needed for some rare actions, it is important to set the $autoload parameter to no.

If the specified option value is equal to the old value, the function does not update anything and terminates its operation.

Expects an unescaped string, i.e., the function saves the passed value as is, and if there are escaped characters, they will be recorded as is. Therefore, if the option has escaped characters, the value should be processed by the wp_unslash() function and then passed to the function.

1 time — 0.001228 sec (very slow) | 50000 times — 9.96 sec (fast) | PHP 7.0.5, WP 4.5.2

Returns

true|false.

  • true, if the value has changed.
  • false, if nothing has changed in the DB or in case of an error.

Usage

update_option( $option, $value, $autoload );
$option_name(string) (required)
The name of the setting to be updated.
$value(string|array|number|object|boolean) (required)
The new value of the setting that will be added to the DB.
$autoload(string|true|false)

Whether to update the option's autoload flag. This flag determines whether to load the option when WordPress starts.

For backward compatibility, 'yes' and 'no' values are also accepted.

true - when first retrieving all site options, the option is added to the global options array. Then, when accessing this option, it is taken from the cache, not from the database.

false - the option will not be loaded with all options. When accessing this option, a separate query to the DB will be made.

null - leave the decision to the standard heuristics of WordPress.

Loading too many options automatically can lead to performance issues, especially if these options are rarely used. Therefore:

  • For options that are used in multiple places on the frontend, it is recommended to load them automatically by setting the value to true.
  • For options that are used only on a few specific URLs, it is recommended not to load them automatically by setting the value to false.
  • For non-existent options, the default value is null, which means that WordPress will determine the autoload value automatically.

Default: null

Examples

1

#1 Update Option Stored in Multi-Dimensional Array

Update multi-dimensional array and retrieve the entire array.

// store in one variable
$multidimensional_options = array(
  'inner_array' => array(
	   'foo'   => 'bar',
	   'hello' => 'world',
   ),
);

// Update entire array
update_option( 'my_multi_options', $multidimensional_options );

// Get entire array
$my_multi_options = get_option( 'my_multi_options' );

/* we get:
Array
(
	[inner_array] => Array
		(
			[foo] => bar
			[hello] => world
		)

)
*/
0

#2 Update the existing option my_option

set it to "new value":

<?php update_option('my_option', 'new value' ); ?>
0

#3 Update the option extract_length to 255.

If this option does not exist, update_option() will create it automatically.

Note that since version 4.2 in update_option() we can specify the autoload parameter, which will be updated if the option exists and passed to add_option() if the option does not exist and must be created...

$newvalue = '255' ;

update_option( 'extract_length', $newvalue, 'no' );
Same for WP version below 4.2:

If the option extract_length does not exist yet, add it using the function add_ooption() where we specify that the option is not loaded automatically (make it private).

$option_name = 'extract_length' ;
$newvalue    = '255' ;

if ( get_option( $option_name ) != $newvalue ) {
	update_option( $option_name, $newvalue );
}
else {
	$deprecated = '';
	$autoload = 'no';
	add_option( $option_name, $newvalue, $deprecated, $autoload );
}
0

#4 Update option only once on the first time installed

The code below will let user change options even after new option set.

function my_switch_theme() {
	update_option( 'thumbnail_size_w', 320 );
	update_option( 'thumbnail_size_h', 180 );
}

add_action('switch_theme', 'my_switch_theme');

If we use after_setup_theme, it will block the options and prevent users change it.

0

#5 true/false case as option value

According to the WordPress Codex (and my experiences developing with WP) note an important subtlety in the return value here:

“True if option value has changed, false if not or if update failed.

It is also recommended on some forums to check for the existence of an option via code:

if ( ! get_option('my_option') ) ...

But I don’t find this works when the option exists and I have set my_option to bool FALSE!

To handle all checking of existence of options, I exploit the update_option subtlety:

if ( FALSE === get_option('my_option') && FALSE === update_option('my_option',FALSE) ) {
add_option( 'my_option', $default_value );
}

The second check yields FALSE when setting the option with the value of FALSE produces no change…therefore if the value truly didn’t exist, it will be added with (in my case) the desired $default_value.

I know this seems extreme, but to the best of my knowledge this is the only way I’ve been able to preserve bool FALSE on my plugin options, and to assert valid actions based on the actual presence of my custom options.

Another variant

According to the WordPress Codex : get_option has $default_value param. will returned when option does not exist. So we can use $default_value as check our code can smaller & faster.

if( get_option( 'otp_name', 'SOME_UNIQUE_VALUE' ) === 'SOME_UNIQUE_VALUE' ){                

	add_option( 'otp_name', 'init_value' ); 
} 

So no update_option call required.

Or use such hack

One workaround is to use as values integers 1 and 0 instead of booleans.

0

#6 Clear the options cache

Option values retrieved via WordPress functions are cached. If you modify an options outside of the Options API, then try to update a cached option, the update will fail and return false.

Use the following method to clear the options cache before trying to get or update the options on the same request:

<?php wp_cache_delete( 'alloptions', 'options' ); ?>
0

#7 Avoid to pass null

Please avoid to pass null as $value, for a false-y value just use 0, false or even an empty string. A null value may lead to potential bugs and side effects.

See this ticket for details.

0

#8 List of all options

Use wp_load_alloptions() to print a list of all options:

$alloptions = wp_load_alloptions();
print_r( $alloptions );

/* we get:
Array
(
	[siteurl] => https://wp-kama.com
	[blogname] => WordPress on your fingertips
	[blogdescription] => Site about the WordPress ...
	[users_can_register] => 1
	...
	...
)
*/

Notes

  • Global. wpdb. $wpdb WordPress database abstraction object.

Changelog

Since 1.0.0 Introduced.
Since 4.2.0 The $autoload parameter was added.
Since 6.7.0 The autoload values 'yes' and 'no' are deprecated.

update_option() code WP 6.8.1

function update_option( $option, $value, $autoload = null ) {
	global $wpdb;

	if ( is_scalar( $option ) ) {
		$option = trim( $option );
	}

	if ( empty( $option ) ) {
		return false;
	}

	/*
	 * Until a proper _deprecated_option() function can be introduced,
	 * redirect requests to deprecated keys to the new, correct ones.
	 */
	$deprecated_keys = array(
		'blacklist_keys'    => 'disallowed_keys',
		'comment_whitelist' => 'comment_previously_approved',
	);

	if ( isset( $deprecated_keys[ $option ] ) && ! wp_installing() ) {
		_deprecated_argument(
			__FUNCTION__,
			'5.5.0',
			sprintf(
				/* translators: 1: Deprecated option key, 2: New option key. */
				__( 'The "%1$s" option key has been renamed to "%2$s".' ),
				$option,
				$deprecated_keys[ $option ]
			)
		);
		return update_option( $deprecated_keys[ $option ], $value, $autoload );
	}

	wp_protect_special_option( $option );

	if ( is_object( $value ) ) {
		$value = clone $value;
	}

	$value     = sanitize_option( $option, $value );
	$old_value = get_option( $option );

	/**
	 * Filters a specific option before its value is (maybe) serialized and updated.
	 *
	 * The dynamic portion of the hook name, `$option`, refers to the option name.
	 *
	 * @since 2.6.0
	 * @since 4.4.0 The `$option` parameter was added.
	 *
	 * @param mixed  $value     The new, unserialized option value.
	 * @param mixed  $old_value The old option value.
	 * @param string $option    Option name.
	 */
	$value = apply_filters( "pre_update_option_{$option}", $value, $old_value, $option );

	/**
	 * Filters an option before its value is (maybe) serialized and updated.
	 *
	 * @since 3.9.0
	 *
	 * @param mixed  $value     The new, unserialized option value.
	 * @param string $option    Name of the option.
	 * @param mixed  $old_value The old option value.
	 */
	$value = apply_filters( 'pre_update_option', $value, $option, $old_value );

	/*
	 * If the new and old values are the same, no need to update.
	 *
	 * Unserialized values will be adequate in most cases. If the unserialized
	 * data differs, the (maybe) serialized data is checked to avoid
	 * unnecessary database calls for otherwise identical object instances.
	 *
	 * See https://core.trac.wordpress.org/ticket/38903
	 */
	if ( $value === $old_value || maybe_serialize( $value ) === maybe_serialize( $old_value ) ) {
		return false;
	}

	/** This filter is documented in wp-includes/option.php */
	if ( apply_filters( "default_option_{$option}", false, $option, false ) === $old_value ) {
		return add_option( $option, $value, '', $autoload );
	}

	$serialized_value = maybe_serialize( $value );

	/**
	 * Fires immediately before an option value is updated.
	 *
	 * @since 2.9.0
	 *
	 * @param string $option    Name of the option to update.
	 * @param mixed  $old_value The old option value.
	 * @param mixed  $value     The new option value.
	 */
	do_action( 'update_option', $option, $old_value, $value );

	$update_args = array(
		'option_value' => $serialized_value,
	);

	if ( null !== $autoload ) {
		$update_args['autoload'] = wp_determine_option_autoload_value( $option, $value, $serialized_value, $autoload );
	} else {
		// Retrieve the current autoload value to reevaluate it in case it was set automatically.
		$raw_autoload = $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
		$allow_values = array( 'auto-on', 'auto-off', 'auto' );
		if ( in_array( $raw_autoload, $allow_values, true ) ) {
			$autoload = wp_determine_option_autoload_value( $option, $value, $serialized_value, $autoload );
			if ( $autoload !== $raw_autoload ) {
				$update_args['autoload'] = $autoload;
			}
		}
	}

	$result = $wpdb->update( $wpdb->options, $update_args, array( 'option_name' => $option ) );
	if ( ! $result ) {
		return false;
	}

	$notoptions = wp_cache_get( 'notoptions', 'options' );

	if ( is_array( $notoptions ) && isset( $notoptions[ $option ] ) ) {
		unset( $notoptions[ $option ] );
		wp_cache_set( 'notoptions', $notoptions, 'options' );
	}

	if ( ! wp_installing() ) {
		if ( ! isset( $update_args['autoload'] ) ) {
			// Update the cached value based on where it is currently cached.
			$alloptions = wp_load_alloptions( true );

			if ( isset( $alloptions[ $option ] ) ) {
				$alloptions[ $option ] = $serialized_value;
				wp_cache_set( 'alloptions', $alloptions, 'options' );
			} else {
				wp_cache_set( $option, $serialized_value, 'options' );
			}
		} elseif ( in_array( $update_args['autoload'], wp_autoload_values_to_autoload(), true ) ) {
			// Delete the individual cache, then set in alloptions cache.
			wp_cache_delete( $option, 'options' );

			$alloptions = wp_load_alloptions( true );

			$alloptions[ $option ] = $serialized_value;
			wp_cache_set( 'alloptions', $alloptions, 'options' );
		} else {
			// Delete the alloptions cache, then set the individual cache.
			$alloptions = wp_load_alloptions( true );

			if ( isset( $alloptions[ $option ] ) ) {
				unset( $alloptions[ $option ] );
				wp_cache_set( 'alloptions', $alloptions, 'options' );
			}

			wp_cache_set( $option, $serialized_value, 'options' );
		}
	}

	/**
	 * Fires after the value of a specific option has been successfully updated.
	 *
	 * The dynamic portion of the hook name, `$option`, refers to the option name.
	 *
	 * @since 2.0.1
	 * @since 4.4.0 The `$option` parameter was added.
	 *
	 * @param mixed  $old_value The old option value.
	 * @param mixed  $value     The new option value.
	 * @param string $option    Option name.
	 */
	do_action( "update_option_{$option}", $old_value, $value, $option );

	/**
	 * Fires after the value of an option has been successfully updated.
	 *
	 * @since 2.9.0
	 *
	 * @param string $option    Name of the updated option.
	 * @param mixed  $old_value The old option value.
	 * @param mixed  $value     The new option value.
	 */
	do_action( 'updated_option', $option, $old_value, $value );

	return true;
}