Title: update_metadata
Published: April 25, 2014
Last modified: February 24, 2026

---

# update_metadata( string $meta_type, int $object_id, string $meta_key, mixed $meta_value, mixed $prev_value ): int|bool

## In this article

 * [Description](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#source)
 * [Hooks](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#hooks)
 * [Related](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#wp--skip-link--target)

Updates metadata for the specified object. If no value already exists for the specified
object ID and metadata key, the metadata will be added.

## 󠀁[Description](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#description)󠁿

For historical reasons both the meta key and the meta value are expected to be “
slashed” (slashes escaped) on input.

## 󠀁[Parameters](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#parameters)󠁿

 `$meta_type`stringrequired

Type of object metadata is for. Accepts `'blog'`, `'post'`, `'comment'`, `'term'`,`'
user'`, or any other object type with an associated meta table.

`$object_id`intrequired

ID of the object metadata is for.

`$meta_key`stringrequired

Metadata key.

`$meta_value`mixedrequired

Metadata value. Must be serializable if non-scalar.

`$prev_value`mixedoptional

Previous value to check before updating.
 If specified, only update existing metadata
entries with this value. Otherwise, update all entries. Default empty string.

## 󠀁[Return](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#return)󠁿

 int|bool The new meta field ID if a field with the given key didn’t exist and was
therefore added, true on successful update, false on failure or if the value passed
to the function is the same as the one that is already in the database.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#source)󠁿

    ```php
    function update_metadata( $meta_type, $object_id, $meta_key, $meta_value, $prev_value = '' ) {
    	global $wpdb;

    	if ( ! $meta_type || ! $meta_key || ! is_numeric( $object_id ) ) {
    		return false;
    	}

    	$object_id = absint( $object_id );
    	if ( ! $object_id ) {
    		return false;
    	}

    	$table = _get_meta_table( $meta_type );
    	if ( ! $table ) {
    		return false;
    	}

    	$meta_subtype = get_object_subtype( $meta_type, $object_id );

    	$column    = sanitize_key( $meta_type . '_id' );
    	$id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id';

    	// expected_slashed ($meta_key)
    	$raw_meta_key = $meta_key;
    	$meta_key     = wp_unslash( $meta_key );
    	$passed_value = $meta_value;
    	$meta_value   = wp_unslash( $meta_value );
    	$meta_value   = sanitize_meta( $meta_key, $meta_value, $meta_type, $meta_subtype );

    	/**
    	 * Short-circuits updating metadata of a specific type.
    	 *
    	 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
    	 * (blog, post, comment, term, user, or any other type with an associated meta table).
    	 * Returning a non-null value will effectively short-circuit the function.
    	 *
    	 * Possible hook names include:
    	 *
    	 *  - `update_blog_metadata`
    	 *  - `update_post_metadata`
    	 *  - `update_comment_metadata`
    	 *  - `update_term_metadata`
    	 *  - `update_user_metadata`
    	 *
    	 * @since 3.1.0
    	 *
    	 * @param null|bool $check      Whether to allow updating metadata for the given type.
    	 * @param int       $object_id  ID of the object metadata is for.
    	 * @param string    $meta_key   Metadata key.
    	 * @param mixed     $meta_value Metadata value. Must be serializable if non-scalar.
    	 * @param mixed     $prev_value Optional. Previous value to check before updating.
    	 *                              If specified, only update existing metadata entries with
    	 *                              this value. Otherwise, update all entries.
    	 */
    	$check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value );
    	if ( null !== $check ) {
    		return (bool) $check;
    	}

    	// Compare existing value to new value if no prev value given and the key exists only once.
    	if ( empty( $prev_value ) ) {
    		$old_value = get_metadata_raw( $meta_type, $object_id, $meta_key );
    		if ( is_countable( $old_value ) && count( $old_value ) === 1 ) {
    			if ( $old_value[0] === $meta_value ) {
    				return false;
    			}
    		}
    	}

    	$meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) );
    	if ( empty( $meta_ids ) ) {
    		return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value );
    	}

    	$_meta_value = $meta_value;
    	$meta_value  = maybe_serialize( $meta_value );

    	$data  = compact( 'meta_value' );
    	$where = array(
    		$column    => $object_id,
    		'meta_key' => $meta_key,
    	);

    	if ( ! empty( $prev_value ) ) {
    		$prev_value          = maybe_serialize( $prev_value );
    		$where['meta_value'] = $prev_value;
    	}

    	foreach ( $meta_ids as $meta_id ) {
    		/**
    		 * Fires immediately before updating metadata of a specific type.
    		 *
    		 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
    		 * (blog, post, comment, term, user, or any other type with an associated meta table).
    		 *
    		 * Possible hook names include:
    		 *
    		 *  - `update_blog_meta`
    		 *  - `update_post_meta`
    		 *  - `update_comment_meta`
    		 *  - `update_term_meta`
    		 *  - `update_user_meta`
    		 *
    		 * @since 2.9.0
    		 *
    		 * @param int    $meta_id     ID of the metadata entry to update.
    		 * @param int    $object_id   ID of the object metadata is for.
    		 * @param string $meta_key    Metadata key.
    		 * @param mixed  $_meta_value Metadata value.
    		 */
    		do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );

    		if ( 'post' === $meta_type ) {
    			/**
    			 * Fires immediately before updating a post's metadata.
    			 *
    			 * @since 2.9.0
    			 *
    			 * @param int    $meta_id    ID of metadata entry to update.
    			 * @param int    $object_id  Post ID.
    			 * @param string $meta_key   Metadata key.
    			 * @param mixed  $meta_value Metadata value. This will be a PHP-serialized string representation of the value
    			 *                           if the value is an array, an object, or itself a PHP-serialized string.
    			 */
    			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
    		}
    	}

    	$result = $wpdb->update( $table, $data, $where );
    	if ( ! $result ) {
    		return false;
    	}

    	wp_cache_delete( $object_id, $meta_type . '_meta' );

    	foreach ( $meta_ids as $meta_id ) {
    		/**
    		 * Fires immediately after updating metadata of a specific type.
    		 *
    		 * The dynamic portion of the hook name, `$meta_type`, refers to the meta object type
    		 * (blog, post, comment, term, user, or any other type with an associated meta table).
    		 *
    		 * Possible hook names include:
    		 *
    		 *  - `updated_blog_meta`
    		 *  - `updated_post_meta`
    		 *  - `updated_comment_meta`
    		 *  - `updated_term_meta`
    		 *  - `updated_user_meta`
    		 *
    		 * @since 2.9.0
    		 *
    		 * @param int    $meta_id     ID of updated metadata entry.
    		 * @param int    $object_id   ID of the object metadata is for.
    		 * @param string $meta_key    Metadata key.
    		 * @param mixed  $_meta_value Metadata value.
    		 */
    		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );

    		if ( 'post' === $meta_type ) {
    			/**
    			 * Fires immediately after updating a post's metadata.
    			 *
    			 * @since 2.9.0
    			 *
    			 * @param int    $meta_id    ID of updated metadata entry.
    			 * @param int    $object_id  Post ID.
    			 * @param string $meta_key   Metadata key.
    			 * @param mixed  $meta_value Metadata value. This will be a PHP-serialized string representation of the value
    			 *                           if the value is an array, an object, or itself a PHP-serialized string.
    			 */
    			do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
    		}
    	}

    	return true;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/meta.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/meta.php#L196)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/meta.php#L196-L372)

## 󠀁[Hooks](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#hooks)󠁿

 [do_action( ‘updated_postmeta’, int $meta_id, int $object_id, string $meta_key, mixed $meta_value )](https://developer.wordpress.org/reference/hooks/updated_postmeta/)

Fires immediately after updating a post’s metadata.

 [do_action( “updated_{$meta_type}_meta”, int $meta_id, int $object_id, string $meta_key, mixed $_meta_value )](https://developer.wordpress.org/reference/hooks/updated_meta_type_meta/)

Fires immediately after updating metadata of a specific type.

 [do_action( ‘update_postmeta’, int $meta_id, int $object_id, string $meta_key, mixed $meta_value )](https://developer.wordpress.org/reference/hooks/update_postmeta/)

Fires immediately before updating a post’s metadata.

 [do_action( “update_{$meta_type}_meta”, int $meta_id, int $object_id, string $meta_key, mixed $_meta_value )](https://developer.wordpress.org/reference/hooks/update_meta_type_meta/)

Fires immediately before updating metadata of a specific type.

 [apply_filters( “update_{$meta_type}_metadata”, null|bool $check, int $object_id, string $meta_key, mixed $meta_value, mixed $prev_value )](https://developer.wordpress.org/reference/hooks/update_meta_type_metadata/)

Short-circuits updating metadata of a specific type.

## 󠀁[Related](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#related)󠁿

| Uses | Description | 
| [get_metadata_raw()](https://developer.wordpress.org/reference/functions/get_metadata_raw/)`wp-includes/meta.php` |

Retrieves raw metadata value for the specified object.

  | 
| [get_object_subtype()](https://developer.wordpress.org/reference/functions/get_object_subtype/)`wp-includes/meta.php` |

Returns the object subtype for a given object ID of a specific type.

  | 
| [wp_cache_delete()](https://developer.wordpress.org/reference/functions/wp_cache_delete/)`wp-includes/cache.php` |

Removes the cache contents matching key and group.

  | 
| [maybe_serialize()](https://developer.wordpress.org/reference/functions/maybe_serialize/)`wp-includes/functions.php` |

Serializes data, if needed.

  | 
| [wpdb::get_col()](https://developer.wordpress.org/reference/classes/wpdb/get_col/)`wp-includes/class-wpdb.php` |

Retrieves one column from the database.

  | 
| [wpdb::update()](https://developer.wordpress.org/reference/classes/wpdb/update/)`wp-includes/class-wpdb.php` |

Updates a row in the table.

  | 
| [_get_meta_table()](https://developer.wordpress.org/reference/functions/_get_meta_table/)`wp-includes/meta.php` |

Retrieves the name of the metadata table for the specified object type.

  | 
| [sanitize_meta()](https://developer.wordpress.org/reference/functions/sanitize_meta/)`wp-includes/meta.php` |

Sanitizes meta value.

  | 
| [add_metadata()](https://developer.wordpress.org/reference/functions/add_metadata/)`wp-includes/meta.php` |

Adds metadata for the specified object.

  | 
| [wp_unslash()](https://developer.wordpress.org/reference/functions/wp_unslash/)`wp-includes/formatting.php` |

Removes slashes from a string or recursively removes slashes from strings within an array.

  | 
| [sanitize_key()](https://developer.wordpress.org/reference/functions/sanitize_key/)`wp-includes/formatting.php` |

Sanitizes a string key.

  | 
| [absint()](https://developer.wordpress.org/reference/functions/absint/)`wp-includes/load.php` |

Converts a value to non-negative integer.

  | 
| [apply_filters()](https://developer.wordpress.org/reference/functions/apply_filters/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to a filter hook.

  | 
| [do_action()](https://developer.wordpress.org/reference/functions/do_action/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to an action hook.

  | 
| [wpdb::prepare()](https://developer.wordpress.org/reference/classes/wpdb/prepare/)`wp-includes/class-wpdb.php` |

Prepares a SQL query for safe execution.

  |

[Show 10 more](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#)

| Used by | Description | 
| [update_site_meta()](https://developer.wordpress.org/reference/functions/update_site_meta/)`wp-includes/ms-site.php` |

Updates metadata for a site.

  | 
| [WP_REST_Autosaves_Controller::create_post_autosave()](https://developer.wordpress.org/reference/classes/wp_rest_autosaves_controller/create_post_autosave/)`wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php` |

Creates autosave for the specified post.

  | 
| [WP_REST_Meta_Fields::update_meta_value()](https://developer.wordpress.org/reference/classes/wp_rest_meta_fields/update_meta_value/)`wp-includes/rest-api/fields/class-wp-rest-meta-fields.php` |

Updates a meta value for an object.

  | 
| [update_term_meta()](https://developer.wordpress.org/reference/functions/update_term_meta/)`wp-includes/taxonomy.php` |

Updates term metadata.

  | 
| [update_user_meta()](https://developer.wordpress.org/reference/functions/update_user_meta/)`wp-includes/user.php` |

Updates user meta field based on user ID.

  | 
| [update_post_meta()](https://developer.wordpress.org/reference/functions/update_post_meta/)`wp-includes/post.php` |

Updates a post meta field based on the given post ID.

  | 
| [update_comment_meta()](https://developer.wordpress.org/reference/functions/update_comment_meta/)`wp-includes/comment.php` |

Updates comment meta field based on comment ID.

  |

[Show 2 more](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#)

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/update_metadata/?output_format=md#changelog)󠁿

| Version | Description | 
| [2.9.0](https://developer.wordpress.org/reference/since/2.9.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fupdate_metadata%2F)
before being able to contribute a note or feedback.