register_uninstall_hook()WP 2.7.0

Registers a function that is called when the plugin is deleted to clean up all traces of the plugin in the system.

When using the function, all actions and codes of the plugin must be inside functions and connected through hooks, i.e., no actions of the plugin should be openly present in the plugin files, because during the deletion process, they will also run and may interfere with the deletion.

The function should be called from the main file, not from functions or classes. Otherwise, the deletion hook may not work.

It is recommended to register the deletion hook only once upon plugin activation, because this function checks and, if necessary, writes the deletion function to a WP option. See https://core.trac.wordpress.org/ticket/31792 See examples below.

This means that your plugin will make one extra request to the DB on every visit to any page of the site, which is not very good for performance.

Also, if the function attached to the hook has changed (its name has changed), then this function needs to be called again with the new value.

uninstall.php

If it is not possible to write the plugin so that its code runs only through hooks, then to delete the plugin use the uninstall.php file:

  1. Create a file uninstall.php in the root directory of the plugin;
  2. Place the code in it that will remove all traces of the plugin.

The uninstall.php file should look like this:

<?php
if( ! defined('WP_UNINSTALL_PLUGIN') )
	exit;

// check passed successfully. Starting from here, we delete options and everything else.
delete_option('my_option');

Before executing the code in the uninstall.php file, it is necessary to check for the presence of the constant WP_UNINSTALL_PLUGIN and only after that delete the traces of the plugin. WP_UNINSTALL_PLUGIN is defined by WordPress at the moment of plugin deletion. Also, the constant WP_UNINSTALL_PLUGIN will not be defined when using the technique of deleting the plugin through a hook; it is defined only after the uninstall.php file has been found in the plugin folder.

When deleting a plugin, it is recommended to use the uninstall.php file where possible, rather than the register_uninstall_hook() function.

If the plugin has an uninstall.php file, then the register_uninstall_hook() function is ignored and all control over the deletion of the plugin is transferred to uninstall.php.

Read more in the article Deleting a Plugin.

No Hooks.

Returns

null. Does not return anything.

Usage

register_uninstall_hook( $file, $callback );
$file(string) (required)
Path to the main plugin file. Usually, the magic constant __FILE__ is used, and register_uninstall_hook() should be called from the main plugin file.
$callback(string/array) (required)
Name of the callback function. For classes, use an array: array( 'Class_Name', 'method_name' );. Here the method must be static.

Examples

A good example of calling three functions: register_uninstall_hook(), register_activation_hook(), register_deactivation_hook(), see in the examples of this function.

1

#1 Registering the uninstall hook, in the plugin file:

// above there should be no open codes, connected directly, not using hooks.

// Perform Uninstall hook inside register_activation_hook
// TO not check NOT autoload options every time

register_activation_hook( __FILE__, 'your_plugin_activate' );

function your_plugin_activate(){
	register_uninstall_hook( __FILE__, 'wm_ya_db_uninstall' );
}

function wm_ya_db_uninstall() {
	delete_option("option_name");
}

// there should be no open codes below, connected directly, not using hooks.

// plugin code

add_action( 'init', 'plugin_function' );

function plugin_function(){
	// plugin function code
}

It is recommended to register the delete hook only once when activating a plugin, because this function checks and, if necessary, writes the delete function to the WP option. See https://core.trac.wordpress.org/ticket/31792

This means that your plugin will make one extra query to the database every time you visit any page on the site, which is not good for performance.

Also, if the function attached to the hook has changed (changed its name), you need to call that function again to rewrite the callback value.

0

#2 Plugin Deletion for OOP

This example shows how to register an uninstall hook for classes.

register_uninstall_hook() should NOT be called inside the class, it must be called outside and point to a class method.

// Perform Uninstall hook inside register_activation_hook
// TO not check NOT autoload options every time

register_activation_hook( __FILE__, 'your_plugin_activate' );

function your_plugin_activate(){
	register_uninstall_hook( __FILE__, array( 'Demo_Class', 'uninstall' ) );
}

class Demo_Class {

	public static function uninstall() {

		if ( ! current_user_can( 'activate_plugins' ) ) {
			return;
		}

		check_admin_referer( 'bulk-plugins' );

		// Important: check if this is the file that
		// was registered at the time the plugin was removed.
		if ( plugin_basename(__FILE__) !== WP_UNINSTALL_PLUGIN )
			return;

		// Uncomment this line to see the function in action
		// exit( var_dump( $_GET ) );
	}

	public function __construct() {
		// Run the plugin: add hooks to the desired functions
	}

}

It's important to uninstall() method must be static OR it must be a simple PHP function, because it writes as string in WP options.

0

#3 File uninstall.php

Instead of using quirky function register_uninstall_hook()? it's better to use uninstall.php file.

An example of what the uninstall.php file should look like

// If the file is accessed directly, close access
if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) 
	exit();

$option_name = 'plugin_option_name';

// For the regular site.
if ( !is_multisite() ) {
	delete_option( $option_name );
} 
// For multisite assembly.
else {
	global $wpdb;

	$blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
	$original_blog_id = get_current_blog_id();

	foreach ( $blog_ids as $blog_id )   {
		switch_to_blog( $blog_id );
		delete_site_option( $option_name );  
	}

	switch_to_blog( $original_blog_id );
}

Changelog

Since 2.7.0 Introduced.

register_uninstall_hook() code WP 6.9

function register_uninstall_hook( $file, $callback ) {
	if ( is_array( $callback ) && is_object( $callback[0] ) ) {
		_doing_it_wrong( __FUNCTION__, __( 'Only a static class method or function can be used in an uninstall hook.' ), '3.1.0' );
		return;
	}

	/*
	 * The option should not be autoloaded, because it is not needed in most
	 * cases. Emphasis should be put on using the 'uninstall.php' way of
	 * uninstalling the plugin.
	 */
	$uninstallable_plugins = (array) get_option( 'uninstall_plugins' );
	$plugin_basename       = plugin_basename( $file );

	if ( ! isset( $uninstallable_plugins[ $plugin_basename ] ) || $uninstallable_plugins[ $plugin_basename ] !== $callback ) {
		$uninstallable_plugins[ $plugin_basename ] = $callback;
		update_option( 'uninstall_plugins', $uninstallable_plugins );
	}
}