WordPress Development Tutorials & Tips

How to Modify Active Plugins


Active WordPress Plugins

Let’s say you have a site that depends on a single plugin functioning. Maybe you have a really nice core utilities plugin that needs to be on or your entire site will go down. That would be a good use case for modifying which plugins WordPress sees as active.

How Plugins Get Loaded

After WordPress loads it’s main environment, must use plugins, and — if you’re on multisite — network activated plugins, it registers a few initial post types, sets up the theme directory, and finally loads the currently active plugins. The relative lines of wp-settings.php:

// Load active plugins.
foreach ( wp_get_active_and_valid_plugins() as $plugin )
    include_once( $plugin );
unset( $plugin );

wp_get_active_and_valid_plugins is what really does the work. It fetchs all the currently active plugins. So let's take a look at that.

 * Returns array of plugin files to be included in global scope.
 * The default directory is wp-content/plugins. To change the default directory
 * manually, define <code>WP_PLUGIN_DIR</code> and <code>WP_PLUGIN_URL</code>
 * in wp-config.php.
 * @access private
 * @since 3.0.0
 * @return array Files to include
function wp_get_active_and_valid_plugins() {
	$plugins = array();
	$active_plugins = (array) get_option( 'active_plugins', array() );

	// Check for hacks file if the option is enabled
	if ( get_option( 'hack_file' ) && file_exists( ABSPATH . 'my-hacks.php' ) ) {
		_deprecated_file( 'my-hacks.php', '1.5' );
		array_unshift( $plugins, ABSPATH . 'my-hacks.php' );

	if ( empty( $active_plugins ) || defined( 'WP_INSTALLING' ) )
		return $plugins;

	$network_plugins = is_multisite() ? wp_get_active_network_plugins() : false;

	foreach ( $active_plugins as $plugin ) {
		if ( ! validate_file( $plugin ) // $plugin must validate as file
			&& '.php' == substr( $plugin, -4 ) // $plugin must end with '.php'
			&& file_exists( WP_PLUGIN_DIR . '/' . $plugin ) // $plugin must exist
			// not already included as a network plugin
			&& ( ! $network_plugins || ! in_array( WP_PLUGIN_DIR . '/' . $plugin, $network_plugins ) )
		$plugins[] = WP_PLUGIN_DIR . '/' . $plugin;
	return $plugins;

The line we're most interested in is get_option( 'active_plugins', array() );. Active plugins are stored in the database.

How Plugins are Stored

Plugins are stored in the {$wpdb->prefix}_options table as an array. Each item in the array is the plugin_basename of the plugin. If your main plugin file is called my-plugin.php and it's stored in the folder my-awesome-plugin, the plugin_basename version of that plugin would be my-awesome-plugin/my-plugin.php. basename(dirname(__FILE__)) . '/' . basename(__FILE__) to put it another way.

wp_get_active_and_valid_plugins takes each plugin basename, validates the file, and combines it with WP_PLUGIN_DIR then returns the array for the includes.

Programmatically Adding Plugins

Because plugins are stored in the database and fetched with get_option, we can use the option_{$option_name} hook to modify the results.

So if want my-plugin/my-plugin.php to always be active:

add_filter('option_active_plugins', 'wpt100_filter_plugins');
function wpt100_filter_plugins($p)
    // make sure it's not already there.
    if(array_search('my-plugin/my-plugin.php', (array)$p) === false) {
        $p[] = 'my-plugin/my-plugin.php';

    return $p;

You can, of course, turn off plugins like this as well. Maybe you want to deactivate a plugin if WP_DEBUG is turned on.

add_filter('option_active_plugins', 'wpt100_filter_plugins');
function wpt100_filter_plugins($p)
    // snip snip

    // remove a plugin
        ($i = array_search('my-plugin/my-plugin.php', (array)$p)) !== false &&
    ) {

    return $p;

The above code would need to loaded sometime before WordPress loads plugins. Your only option, short of hacking into the core (don't do that, by the way, bad idea) is a must use plugin.