Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've created a plugin, and of course being me, I wanted to go with a nice OO approach. Now what I've been doing is to create this class and then just below create an instance of this class:

class ClassName {

    public function __construct(){

    }
}

$class_instance = new ClassName();  

I'm assuming there is a more WP way to have this class initiated, and then I came across people saying that they prefer to have an init() function than a __construct() one. And similarly I found the a few people using following hook:

class ClassName {

    public function init(){

    }
}
add_action( 'load-plugins.php', array( 'ClassName', 'init' ) );

What is generally considered the best way to create a WP class instance on load and have this as a globally accessibly variable?

NOTE: As an interesting side point, I've noticed that while register_activation_hook() can be called from within the __construct, it cannot be called from within the init() using the second example. Perhaps someone could enlighten me on this point.

Edit: Thanks for all the answers, there clearly is a fair bit of debate as to how handle the initialization within the class itself, but I think there's generally a pretty good consensus that add_action( 'plugins_loaded', ...); is the best way to actually kick it off...

Edit: Just to confuse matters, I've also seen this used (although I wouldn't use this method myself because turning a nicely OO class into a function seems to defeat the point of it):

// Start up this plugin
add_action( 'init', 'ClassName' );
function ClassName() {
    global $class_name;
    $class_name = new ClassName();
}
share|improve this question
    
Regarding last edit, if that's contained in the same plugin file as the class, it becomes somewhat useless. You may as well instantiate the class as per the method I describe. Even if its in a separate file, its still somewhat pointless. Only use case I can see is if you want to create a wrapper function that enables you to instantiate a class outside of your plugin files, within themes and so on. Even so, I'd have to ask what logic lay behind that because proper use of conditionals and hooks should allow fine grain control over instantiation allowing you to focus on using the plugin instead. –  userabuser Oct 23 '12 at 16:14
    
I kinda agree with this, but I thought it worth putting in as I found it in a couple of WP plugins. –  kalpaitch Oct 24 '12 at 8:40
add comment

3 Answers

up vote 17 down vote accepted

Good question, there are a number of approaches and it depends on what you want to achieve.

I often do;

add_action( 'plugins_loaded', array( 'someClassy', 'init' ));

class someClassy {

    public static function init() {
        $class = __CLASS__;
        new $class;
    }

    public function __construct() {
           //construct what you see fit here...
    }

    //etc...
}

A more thorough an indepth example which came about as a result of some recent discussions on this very topic within the chat room can be seen in this gist by WPSE member toscho.

The empty constructor approach.

Here is an excerpt of advantages/disadvantages taken from the above gist which exemplifies the empty constructor approach in full.

  • Advantages:

    • Unit tests can create new instances without activating any hooks automatically. No Singleton.

    • No global variable needed.

    • Whoever wants to work with the plugin instance can just call T5_Plugin_Class_Demo::get_instance().

    • Easy to deactivate.

    • Still real OOP: no working methods are static.

  • Disadvantage:

    • Maybe harder to read?

The disadvantage in my opinion is a weak one at that which is why it would have to be my favored approach, however not the only one I use. In fact several other heavy weights will no doubt chime in on this topic with their take on the subject shortly because there are some good opinions surrounding this topic that should be voiced.


note: I need to find the gist example from toscho that ran through 3 or 4 comparisons of how to instantiate a class within a plugin that looked at the pros and cons of each, which the above link was the favored way to do it, but the other examples provide a good contrast to this topic. Hopefully toscho still has that on file.

Note: The WPSE Answer to this topic with relevant examples and comparisons. Also the best solution for instance a class in WordPress.

add_shortcode( 'baztag', array( My_Plugin::get_instance(), 'foo' ) );
class My_Plugin {

    private $var = 'foo';

    protected static $instance = NULL;

    public static function get_instance() {

        // create an object
        NULL === self::$instance and self::$instance = new self;

        return self::$instance; // return the object
    }

    public function foo() {

        return $this->var; // never echo or print in a shortcode!
    }
}
share|improve this answer
    
what would be the difference between add_action('plugins_loaded',...); and add_action('load-plugins.php',...); The example I took used the latter –  kalpaitch Oct 22 '12 at 9:46
1  
From what I understand load-plugins.php, although it works, is associated with the core update.php file and is not part of the usual default actions that should be relied upon when concerning the sequence of events that fire during initialization and for that reason I prefer to use those hooks that do apply, in this case plugins_loaded. This is what I often refer to as a quick snapshot of what happens when Action Reference. My explanation is not complete in its entirety. –  userabuser Oct 22 '12 at 10:00
2  
I like this singleton-like approach. However, I question using plugins_loaded as your initializing action hook. This hook is meant to be run after all plugins have loaded. By hooking in after it, you are kind of hijacking that hook, and may fun into conflicts or startup-sequence issues with other plugins or themes that hook into plugins_loaded. I wouldn't hook into any action to run your initialization method. The plugin architecture was designed to run inline, not on an action. –  Tom Auger Oct 23 '12 at 21:25
2  
Note that if you use register_activation_hook() you need to call that function before the plugins_loaded action has been triggered. –  Geert Oct 31 '12 at 9:52
1  
As additional information, see this post from @mikeschinkel and the dicuss in the comments. hardcorewp.com/2012/… –  bueltge Jan 3 '13 at 11:24
show 9 more comments

I use following structure:

Prefix_Example_Plugin::on_load();

/**
 * Example of initial class-based plugin load.
 */
class Prefix_Example_Plugin {

    /**
     * Hooks init (nothing else) and calls things that need to run right away.
     */
    static function on_load() {

        // if needed kill switch goes here (if disable constant defined then return)

        add_action( 'init', array( __CLASS__, 'init' ) );
    }

    /**
     * Further hooks setup, loading files, etc.
     *
     * Note that for hooked methods name equals hook (when possible).
     */
    static function init(  ) {


    }
}

Notes:

  • has defined place for things that need to run right away
  • disable/override for tweaks is easy (unhook one init method)
  • I don't think I ever used/needed object of plugin class - requires keeping track of it, etc; this is really fake namespacing by purpose, not OOP (most of the time)

Disclaimer I don't use unit tests yet (so many things on myplate) and I hear that static can be less preferable for them. Do your research on this if you need to unit test it.

share|improve this answer
2  
I know people big on unit testing really don't like static / singleton solutions. I think if you fully understand what you are attempting to achieve by using static and are at least aware of the ramifications of doing so then its perfectly fine to implement such methods. Good topics surrounding this over at Stack Overflow –  userabuser Oct 22 '12 at 10:21
    
This made me really think. So why use a Classes then and not just go back to simple prefixed functions. Do we do this just to have cleaner function/method names? I mean having them nested with a "static" b4 them is it that much more readable? The chance of having a name conflict is about the same as for a single class name if you use propper prefixes or am I missing something? –  James Mitch May 28 '13 at 5:52
    
@JamesMitch yes, all-static methods is mostly just functions with fake namespace as used in WP. However classes do have some advantages over pure functions even in this case, such as autoload and inheritance. Lately I have been moving from static methods and towards real instantiated objects organized by dependency injection container. –  Rarst May 28 '13 at 10:35
add comment

It all depends on functionality.

I once made a plugin that registered scripts when the constructor was called so I had to hook it at the wp_enqueue_scripts hook.

If you want to call it when your functions.php file is loaded, you might as well create an instance yourself $class_instance = new ClassName(); as you mentioned.

You might want to consider speed and memory usage. I'm not aware of any, but I can imagine there are uncalled hooks in some cases. By creating your instance at that hook you might save some server resources.

share|improve this answer
    
Cool thanks for that, I suppose there are two points to the above question as well. The other being whether __construct is suitable or whether init() is a better way to initialize the class. –  kalpaitch Oct 22 '12 at 9:40
1  
Well I'd go for an static init() method so the class instance is called in the class' scope instead of another scope where you could possibly overwrite existing variables. –  Tim S. Oct 22 '12 at 9:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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