2026年11月14日
2026年11月14日
WordPress User Meta: get_user_meta, Profile Fields and WP-CLI
This article is a localized edition of the Japanese original. Read the Japanese original
User meta is how WordPress stores extra information for each user, such as a phone number, a company name or a point balance. Each value is saved in the wp_usermeta table (when your table prefix is wp_) as a row of user ID, key and value. You read and write it from a plugin or your theme's functions.php with a set of dedicated functions.
The behavior of the functions and hooks in this article was checked against the WordPress core source code (6.9).
The four basic functions
<?php
$user_id = get_current_user_id(); // ID of the logged-in user (0 if not logged in)
// Add: with the 4th argument set to true, nothing is added if the key already exists
add_user_meta( $user_id, 'myplugin_points', 0, true );
// Get: with the 3rd argument set to true, a single value is returned
$points = (int) get_user_meta( $user_id, 'myplugin_points', true );
// Update: the key is added if it does not exist
update_user_meta( $user_id, 'myplugin_points', $points + 10 );
// Delete
delete_user_meta( $user_id, 'myplugin_points' );
| Function | Return value |
|---|---|
add_user_meta() |
The ID of the new row, or false if nothing was added |
get_user_meta( $id, $key, true ) |
The value, or an empty string '' if the key does not exist |
get_user_meta( $id, $key, false ) |
An array of all values for that key, or an empty array if there are none |
get_user_meta( $id ) |
Without a key, all meta for that user (an array per key) |
update_user_meta() |
The new row ID when the key was added, true when it was updated, and false when the value was unchanged or the update failed |
delete_user_meta() |
true if deleted, false if not |
Watch the type of the value you get back. Numbers and booleans are stored as strings, so saving 100 returns "100", and saving false returns "". Cast with (int) or similar when you need a number. If you save an array, WordPress serializes it on save and turns it back into an array when you read it.
Give your keys a prefix such as your plugin name so they do not collide with other plugins (this article uses myplugin_).
Add fields to the profile screen
This example adds phone number and company name fields to the Profile and Edit User screens in the admin.
| Hook | When it runs |
|---|---|
show_user_profile |
When your own profile is displayed |
edit_user_profile |
When the edit screen of another user is displayed |
personal_options_update |
When your own profile is saved |
edit_user_profile_update |
When another user is saved from the edit screen |
<?php
// Display the fields ($user is a WP_User)
add_action( 'show_user_profile', 'myplugin_profile_fields' );
add_action( 'edit_user_profile', 'myplugin_profile_fields' );
function myplugin_profile_fields( $user ) {
$phone = get_user_meta( $user->ID, 'myplugin_phone', true );
$company = get_user_meta( $user->ID, 'myplugin_company', true );
?>
<h2>Additional information</h2>
<table class="form-table" role="presentation">
<tr>
<th><label for="myplugin_phone">Phone number</label></th>
<td><input type="tel" id="myplugin_phone" name="myplugin_phone" value="<?php echo esc_attr( $phone ); ?>" class="regular-text"></td>
</tr>
<tr>
<th><label for="myplugin_company">Company</label></th>
<td><input type="text" id="myplugin_company" name="myplugin_company" value="<?php echo esc_attr( $company ); ?>" class="regular-text"></td>
</tr>
</table>
<?php
}
// Save the fields
add_action( 'personal_options_update', 'myplugin_save_profile_fields' );
add_action( 'edit_user_profile_update', 'myplugin_save_profile_fields' );
function myplugin_save_profile_fields( $user_id ) {
if ( ! current_user_can( 'edit_user', $user_id ) ) {
return;
}
if ( isset( $_POST['myplugin_phone'] ) ) {
update_user_meta( $user_id, 'myplugin_phone', sanitize_text_field( wp_unslash( $_POST['myplugin_phone'] ) ) );
}
if ( isset( $_POST['myplugin_company'] ) ) {
update_user_meta( $user_id, 'myplugin_company', sanitize_text_field( wp_unslash( $_POST['myplugin_company'] ) ) );
}
}
- Before the save hooks run, core's
wp-admin/user-edit.phpalready verifies the form nonce withcheck_admin_referer( 'update-user_' . $user_id ), so you do not need your own nonce for these fields. Check permissions withcurrent_user_can( 'edit_user', $user_id ). - WordPress adds backslashes to
$_POSTvalues, so remove them withwp_unslash()and then clean the value withsanitize_text_field().
To confirm it works, save the profile, reload the screen and check that your values are still there.
Filter users by meta value
Pass meta_key and related arguments to get_users() to filter users by a meta value. Set meta_type to NUMERIC to compare as numbers. Without it, values are compared as strings, and "9" counts as greater than "100".
<?php
// 20 users with 100 points or more, highest first
$users = get_users( array(
'meta_key' => 'myplugin_points',
'meta_value' => 100,
'meta_compare' => '>=',
'meta_type' => 'NUMERIC',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'number' => 20,
) );
foreach ( $users as $user ) {
$points = (int) get_user_meta( $user->ID, 'myplugin_points', true );
echo esc_html( $user->display_name . ': ' . $points . ' points' ) . '<br>';
}
// Users who have no phone number meta
$no_phone = get_users( array(
'meta_query' => array(
array(
'key' => 'myplugin_phone',
'compare' => 'NOT EXISTS',
),
),
) );
Filtering by meta value gets slow when you have many users. For lists you use often, consider caching the result for a while (for example in a transient).
View and change user meta with WP-CLI
The WP-CLI wp user meta command lets you view and change user meta. For <user>, give a user ID, login name or email address.
# Show all meta for user ID 1
wp user meta list 1
# Show the value of one key
wp user meta get 1 myplugin_points
# Change a value (added if the key does not exist)
wp user meta update 1 myplugin_points 500
# Delete
wp user meta delete 1 myplugin_points
wp user list accepts the same arguments as get_users() in the form --argument=value.
# List users with more than 0 points
wp user list --meta_key=myplugin_points --meta_value=0 --meta_compare='>' --meta_type=NUMERIC --fields=ID,user_login,display_name
# Show only the number of matching users
wp user list --meta_key=myplugin_points --meta_value=0 --meta_compare='>' --meta_type=NUMERIC --format=count
Creating users, changing roles and more are covered in How to use the WP-CLI user command.
Set an initial value for all users at once
Here is an example for when a new plugin feature needs an initial value for every existing user. Long code passed to wp eval easily breaks on shell quoting and escaping, so put it in a PHP file and run it with wp eval-file.
<?php
// init-points.php (run: wp eval-file init-points.php)
$user_ids = get_users( array( 'fields' => 'ID' ) );
$count = 0;
foreach ( $user_ids as $user_id ) {
// Set 0 only for users who do not have the key yet
if ( ! metadata_exists( 'user', (int) $user_id, 'myplugin_points' ) ) {
add_user_meta( (int) $user_id, 'myplugin_points', 0, true );
$count++;
}
}
WP_CLI::success( $count . ' users initialized' );
metadata_exists()only checks whether the key exists. If you test the result ofget_user_meta()instead, users whose value is0are also treated as having no value.- On multisite,
get_users()returns only users of the current site by default. - Back up the database before running it on production.
Use user meta in the REST API
By default, user meta is not included in the REST API (/wp-json/wp/v2/users/<id>). To read or write it from the block editor or an external app, register it with register_meta() and set show_in_rest to true.
<?php
add_action( 'init', function () {
register_meta( 'user', 'myplugin_points', array(
'type' => 'integer',
'single' => true,
'default' => 0,
'show_in_rest' => true,
'sanitize_callback' => 'absint',
) );
} );
Once a default is registered, get_user_meta( $id, 'myplugin_points', true ) returns that value (here 0) instead of an empty string for users who do not have the key.
After registration, the value appears under meta in the user's REST response, and anyone allowed to edit that user can update it. Keys that start with _ are treated as protected meta and cannot be updated over REST unless an auth_callback allows it.
Things to watch out for
- Do not store secrets such as passwords or API keys in user meta as plain text.
- To remove the meta when your plugin is deleted, delete it for all users in
uninstall.php, for example withdelete_metadata( 'user', 0, 'myplugin_points', '', true )(the 5th argumenttruetargets every user). - Meta attached to posts (custom fields) uses different functions (such as
get_post_meta()) and a different table (wp_postmeta).
Summary
- Read and write user meta with
add_user_meta(),get_user_meta(),update_user_meta()anddelete_user_meta(); values come back as strings, so convert the type when needed - Show profile fields with
show_user_profileandedit_user_profile, and save them withpersonal_options_updateandedit_user_profile_updateafter checking permissions - Set
meta_typetoNUMERICwhen filtering by numbers - In WP-CLI, use
wp user metato view and change values, and run bulk jobs withwp eval-file
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)