In our tutorial "Using Classes as Code Wrappers for WordPress Plugins" we took a plugin that used a global function for its filter hook and converted it to using a PHP class as a code wrapper. Unfortunately the approach we showed didn't allow other plugins and/or themes to remove or chain the actions and/or filters if needed.

Let's explore the hook removal problem. We'll start with the example from the prior tutorial:

<?php /* * Plugin Name: Thanks for Reading */ class Thanks_For_Reading_Plugin { function __construct ( ) { add_filter ( 'the_content' , array ( $this , 'the_content' ) ) ; } function the_content ( $content ) { return $content . '<p>Thanks for Reading!</p>' ; } } new Thanks_For_Reading_Plugin ( ) ; <?php /* * Plugin Name: Thanks for Reading */ class Thanks_For_Reading_Plugin { function __construct() { add_filter( 'the_content', array( $this, 'the_content' ) ); } function the_content( $content ) { return $content . '<p>Thanks for Reading!</p>'; } } new Thanks_For_Reading_Plugin();

Use a Global Variable for the Instance?

We could assign a global variable when we create the plugin's instance, and that is what a lot of plugins do:

$thanks_for_reading = new Thanks_For_Reading_Plugin ( ) ; $thanks_for_reading = new Thanks_For_Reading_Plugin();

Others could then use this approach to remove our filter:

global $thanks_for_reading ; remove_filter ( 'the_content' , array ( $thanks_for_reading , 'the_content' ) ) ; global $thanks_for_reading; remove_filter( 'the_content', array( $thanks_for_reading, 'the_content' ) );

Unfortunately this adds yet another global variable that may conflict with other plugins or themes. It also adds to the list of global variables making for more to scan in IDE debuggers like PhpStorm. For these and other reasons we don't recommend using global variables for plugins like this.

Use a Private Static Property Instead

Rather than use global we'll declare a private static variable we'll call $_this .

class Thanks_For_Reading_Plugin { private static $_this ; ... } class Thanks_For_Reading_Plugin { private static $_this; ... }

The Static Declaration

The static declaration in PHP means that all instances of the class share the same single value. But as we only want one instance of this class we use static to allow us to access the instance using the class name, as you'll see below.

The Private Qualifier

In PHP the private variable qualifier "hides" the variable to any code outside of the class. In our case we want to ensure other code doesn't change its value accidentally, again as you'll see below.

Capture the Plugin's Instance

Inside the constructor we'll assign the object's instance from the $this variable to the static variable self::$_this :

class Thanks_For_Reading_Plugin { private static $_this ; function __construct ( ) { self :: $_this = $this ; ... } ... } class Thanks_For_Reading_Plugin { private static $_this; function __construct() { self::$_this = $this; ... } ... }

Add a Read-Only Access Function

Next add a static function to the class which we'll name this() and have it return the value of self::$_this . This function will be public [^public-methods] by default providing read-only access to the single instance used by the plugin's class:

class Thanks_For_Reading_Plugin { private static $_this ; function __construct ( ) { self :: $_this = $this ; ... } static function this ( ) { return self :: $_this ; } ... } class Thanks_For_Reading_Plugin { private static $_this; function __construct() { self::$_this = $this; ... } static function this() { return self::$_this; } ... }

To access the plugin's instance from outside the class simply call this() using the syntax for calling static methods:

$instance = Thanks_For_Reading_Plugin :: this ( ) ; $instance = Thanks_For_Reading_Plugin::this();

Removing the Filter

We've now enabled other plugins and themes to remove or chain any of our plugin's filters they may need to. Here's code they can use to remove the 'the_content' filter from our example plugin:

$instance = Thanks_For_Reading_Plugin :: this ( ) ; remove_filter ( 'the_content' , array ( $instance , 'the_content' ) ) ; $instance = Thanks_For_Reading_Plugin::this(); remove_filter( 'the_content', array( $instance, 'the_content' ) );

The Complete Example

Here is the entire example for viewing this post's code in context:

<?php /* * Plugin Name: Thanks for Reading */ class Thanks_For_Reading_Plugin { private static $_this ; function __construct ( ) { self :: $_this = $this ; add_filter ( 'the_content' , array ( $this , 'the_content' ) ) ; } static function this ( ) { return self :: $_this ; } function the_content ( $content ) { return $content . '<p>Thanks for Reading!</p>' ; } } new Thanks_For_Reading_Plugin ( ) ; <?php /* * Plugin Name: Thanks for Reading */ class Thanks_For_Reading_Plugin { private static $_this; function __construct() { self::$_this = $this; add_filter( 'the_content', array( $this, 'the_content' ) ); } static function this() { return self::$_this; } function the_content( $content ) { return $content . '<p>Thanks for Reading!</p>'; } } new Thanks_For_Reading_Plugin();

Summary

If you use classes as code wrappers for your WordPress plugins, which we recommend, you should take the tiny bit of extra effort to enable your users the flexibility they might need to remove or chain your filters. Fortunately the code required is almost completely copy-and-paste so it doesn't require in-depth understanding to get started; just grab the code template below and get started with your plugin:

Related Links

There are other posts on the web related to this topic:

We're haven't read each of these in-depth so can't vouch for them all, we're just telling you they exist. Caveat emptor.

Follow up Posts

If you'd like to learn more about writing class-based WordPress plugins you might be interested in this post too: