As a plugin developer, I want to ensure that my plugin doesn't leave any custom settings left behind from my plugin when upgrading from v1.0 to v2.0.

Whenever a user uninstalls my plugin, I've created an uninstall.php file (standard practice) which automatically removes all of my plugin's settings for a clean removal:

if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) { // Exit if accessed directly

// Remove all plugin options with the prefix "myplugin_"
global $wpdb;
$plugin_options = $wpdb -> get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'myplugin_%'" );

foreach( $plugin_options as $option ) {
    delete_option( $option -> option_name );

This script automatically removes all options that have the prefix of myplugin_ such as:


However, I am already working on a new version of my plugin with new options in my settings page. If a user has an older version of my plugin and is upgrading to the next version without uninstalling it, how do I ensure all of my old plugin options are removed for a clean upgrade? Does the uninstall.php file automatically run when a user is upgrading to a new version of my plugin?

3 Answers 3


Does your plugin use a version number? On plugin activation you can compare the version number and use the code you have above to remove the 'old' options if they exist.

if ( $myplugin_version > 3.0 ) {
    // Remove all plugin options with the prefix "myplugin_"

Each plugin should have a version number, like on the comments for the meta data of WordPress or much easier in a constant, var of the plugin. This version helps you to remove data only after, before a version.

You should use the php function version_compare to validate the version.

If you have no version inside your code as constant or var, you can also use the version from the head's meta data of the plugin.

Meta like this:

<?php # -*- coding: utf-8 -*-
 * Plugin Name: WPSE 238422
 * Description: foo.
 * Author:      Frank
 * Author URI:  http://bueltge.de
 * Version:     4.6.99
 * Text Domain: bar
 * License:     GPLv2+
 * Network:     true

To get the version of the head, this function is helpful.

     * Return plugin comment data
     * @param   string $value default = 'Version'
     *                        Name, PluginURI, TextDomain, Description, Author, AuthorURI, TextDomain, DomainPath, Network, Title
     * @param   bool   $echo
     * @return  string
    public function get_plugin_data( $value = 'Version', $echo = FALSE ) {

        static $plugin_data = array();

        // fetch the data just once.
        if ( isset( $plugin_data[ $value ] ) ) {
            return $plugin_data[ $value ];

        if ( ! function_exists( 'get_plugin_data' ) ) {
            require_once ABSPATH . '/wp-admin/includes/plugin.php';

        $plugin_data  = get_plugin_data( __FILE__ );
        $plugin_value = empty ( $plugin_data[ $value ] ) ? '' : $plugin_data[ $value ];

        if ( $echo ) {
            echo $plugin_value;

        return $plugin_value;

If you use this, maybe you can check like the follow example. version_compare( $this->get_plugin_data(), '4.6-RC1', '<' );

  • Thanks for the answer. Yes, to clarify I do have a version number for my plugin. It's only in the head of the plugin's metadata though and not as a constant or var. Is it better to define a variable with my plugin version moving forward? Otherwise, if it makes no difference to grab it from the header's metadata, then that works for me. Commented Sep 7, 2016 at 10:54
  • That works also, and have the benefit is it not redundant. But the work to get the value from the meta data is not really fast.
    – bueltge
    Commented Sep 7, 2016 at 11:04
  • @EthanJinksO'Sullivan Please, if the answer is helpful, please set the hook on the answer that other readers see, it works, is helpful.
    – bueltge
    Commented Sep 8, 2016 at 8:07
  • 1
    Haven't forgotten about this answer. I didn't get to test out the code yet, but I plan on it this weekend. I'll give you an update by then. Thanks. Commented Sep 8, 2016 at 11:52
  • Testing out this code now, thank you. Does this function need to run in my plugin's root file where the meta is stored (plugin/plugin.php)? Also, similar to the register_activation_hook hook, would the upgrader_process_complete hook be ideal to use to run my custom function in my uninstall.php? Commented Sep 29, 2016 at 2:06

In my upcoming plugin v2.0.0, I've added an option which will store the plugin's version to compare to in the future on the next update.

As a workaround, I've implemented a check to see if myplugin_version is less than 2.0.0 or if it doesn't exist, remove plugin options with the myplugin_ prefix:

# If the plugin version is lower or not defined, remove plugin options
if ( ( get_option( 'myplugin_version' ) < '2.0.0' ) || ! get_option( 'myplugin_version' ) ) {
    # Remove options with the prefix "myplugin_"
    foreach ( wp_load_alloptions() as $option => $value ) {
        if ( strpos( $option, 'myplugin_' ) === 0 ) {
            delete_option( $option );
    # Add options for new plugin version
    update_option( 'myplugin_version', '2.0.0' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.