wp_delete_user( int $id, int $reassign = null ): bool
- Since
- 2.0.0
- Source
wp-admin/includes/user.php:350
Description
Note that on a Multisite installation the user only gets removed from the site and does not get deleted from the database.
If the $reassign parameter is not assigned to a user ID, then all posts will be deleted of that user. The action 'delete_user' that is passed the user ID being deleted will be run after the posts are either reassigned or deleted.
The user meta will also be deleted that are for that user ID.
Compatibility
- WordPress
- since 2.0.0
- PHP
- 7.4–8.6-dev
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.
Parameters
$idint- User ID.
$reassignintoptional- Reassign posts and links to new User ID.Default:
null
Return value
bool- True when finished.
Performance profile
How much work a call to wp_delete_user() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.
- Cost class
- Heavy
- Scaling
- Scales with input
- Instructions
- 6–115
- Plugin surface
- 3 hooks
- Called by
- 1
Reaches the database via ->get_col().
The body loops, so the work grows with what you pass in.
Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 218.
Third-party callbacks on 'delete_user', 'post_types_to_delete_with_user', 'deleted_user' run inside this call, and their cost is not bounded by anything here.
1 place in core call this, so the cost is paid more often than your own code shows.
What it touches
- hookthird-party callbacks
do_action()called directly - sqldatabase query
->get_col()called directly - querycontent query
get_post()one call below wp_delete_user() - cacheobject cache
wp_cache_delete()one call below wp_delete_user()
Further down the call graph this can also reach option, serialize and transient. Those are the worst case, several calls deep and usually down an error path, not what a normal call pays.
What one call costs · 6 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost wp_delete_user() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
!$id | 6 | none |
$id && !->exists() | 15 | ->exists() |
$id && ->exists() && $reassign === null && is_multisite() | 89–99 | ->exists(), do_action(), get_post_types(), apply_filters(), ->prepare(), ->get_col(), ->prepare(), ->get_col(), is_multisite(), get_current_blog_id(), remove_user_from_blog(), clean_user_cache(), do_action() |
$id && ->exists() && $reassign !== null && is_multisite() | 92–100 | ->exists(), do_action(), ->prepare(), ->get_col(), post_author(), ->prepare(), ->get_col(), link_owner(), is_multisite(), get_current_blog_id(), remove_user_from_blog(), clean_user_cache(), do_action() |
$id && ->exists() && $reassign === null && !is_multisite() | 103–114 | ->exists(), do_action(), get_post_types(), apply_filters(), ->prepare(), ->get_col(), ->prepare(), ->get_col(), is_multisite(), ->prepare(), ->get_col(), ID(), clean_user_cache(), do_action() |
$id && ->exists() && $reassign !== null && !is_multisite() | 106–115 | ->exists(), do_action(), ->prepare(), ->get_col(), post_author(), ->prepare(), ->get_col(), link_owner(), is_multisite(), ->prepare(), ->get_col(), ID(), clean_user_cache(), do_action() |
Across PHP versions
| PHP | Compiled | Executed | Branches | Notes |
|---|---|---|---|---|
| 8.6-dev | 218 | 6–115 | 25 | |
| 8.5 | 218 | 6–115 | 25 | |
| 8.4 | 218 | 6–115 | 25 | 5 fewer instructions than PHP 8.3 |
| 8.3 | 223 | 8–119 | 25 | |
| 8.2 | 223 | 8–119 | 25 | |
| 8.1 | 223 | 8–119 | 25 | |
| 7.4 | 223 | 8–119 | 25 |
An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.
Hooks and filters fired · 3
3 hooks fire while wp_delete_user() runs, in this order:
- do_action( delete_user )actionline 385 (+35 into the body)
Fires immediately before a user is deleted from the site.
- apply_filters( post_types_to_delete_with_user )filterline 405 (+55 into the body)
Filters the list of post types to delete with a user.
- do_action( deleted_user )actionline 468 (+118 into the body)
Fires immediately after a user is deleted from the site.
Uses · 14
- do_action()Calls the callback functions that have been added to an action hook.
- get_post_types()Gets a list of all registered post type objects.
- post_type_supports()Checks a post type's support for a given feature.
- apply_filters()Calls the callback functions that have been added to a filter hook.
- wp_delete_post()Trashes or deletes a post or page.
- wp_delete_link()Deletes a specified link from the database.
- clean_post_cache()Will clean the post in the cache.
- clean_bookmark_cache()Deletes the bookmark cache.
- is_multisite()Determines whether Multisite is enabled.
- remove_user_from_blog()Removes a user from a blog.
- get_current_blog_id()Retrieves the current site ID.
- delete_metadata_by_mid()Deletes metadata by meta ID.
Show all 14
- clean_user_cache()Cleans all user caches.
- WP_User::__construct()Constructor.
Used by · 1
- WP_REST_Users_Controller::delete_item()Deletes a single user.
Source code
function wp_delete_user( $id, $reassign = null ) { global $wpdb; if ( ! is_numeric( $id ) ) { return false; } $id = (int) $id; $user = new WP_User( $id ); if ( ! $user->exists() ) { return false; } // Normalize $reassign to null or a user ID. 'novalue' was an older default. if ( 'novalue' === $reassign ) { $reassign = null; } elseif ( null !== $reassign ) { $reassign = (int) $reassign; } /** * Fires immediately before a user is deleted from the site. * * Note that on a Multisite installation the user only gets removed from the site * and does not get deleted from the database. * * @since 2.0.0 * @since 5.5.0 Added the `$user` parameter. * * @param int $id ID of the user to delete. * @param int|null $reassign ID of the user to reassign posts and links to. * Default null, for no reassignment. * @param WP_User $user WP_User object of the user to delete. */ do_action( 'delete_user', $id, $reassign, $user ); if ( null === $reassign ) { $post_types_to_delete = array(); foreach ( get_post_types( array(), 'objects' ) as $post_type ) { if ( $post_type->delete_with_user ) { $post_types_to_delete[] = $post_type->name; } elseif ( null === $post_type->delete_with_user && post_type_supports( $post_type->name, 'author' ) ) { $post_types_to_delete[] = $post_type->name; } } /** * Filters the list of post types to delete with a user. * * @since 3.4.0 * * @param string[] $post_types_to_delete Array of post types to delete. * @param int $id User ID. */ $post_types_to_delete = apply_filters( 'post_types_to_delete_with_user', $post_types_to_delete, $id ); $post_types_to_delete = implode( "', '", $post_types_to_delete ); $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d AND post_type IN ('$post_types_to_delete')", $id ) ); if ( $post_ids ) { foreach ( $post_ids as $post_id ) { wp_delete_post( $post_id ); } } // Clean links. $link_ids = $wpdb->get_col( $wpdb->prepare( "SELECT link_id FROM $wpdb->links WHERE link_owner = %d", $id ) ); if ( $link_ids ) { foreach ( $link_ids as $link_id ) { wp_delete_link( $link_id ); } } } else { $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_author = %d", $id ) ); $wpdb->update( $wpdb->posts, array( 'post_author' => $reassign ), array( 'post_author' => $id ) ); if ( ! empty( $post_ids ) ) { foreach ( $post_ids as $post_id ) { clean_post_cache( $post_id ); } }Changelog
Introduced in 2.0.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
About this page
- Parsed data
- Generated from the wordpress-develop 6.8.8 tag, from
src/wp-admin/includes/user.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it. - Corrections
- Something wrong on this page? Report it and it gets fixed in the next regeneration.