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

4 Answers 4

up vote 24 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

Arriving here exactly 2 years after original question was asked, there are a few things I want to point out. (Don't ask me to point out a lot of things, ever).

Proper hook

To instantiate a plugin class, the proper hook should be used. There is no a general rule for which it is, because it depends on what the class does.

Using a very early hook like "plugins_loaded" often make no sense because an hook like that is fired for admin, frontend and AJAX requests, but very often a later hook is far better because allow to instantiate plugin classes only when needed.

E.g. a class that does stuff for templates can be instantiated on "template_redirect".

Generally speaking is very rare that a class needs to be instantiated before "wp_loaded" has been fired.

No God Class

Most of all the classes used as example in older answers use a class named like "Prefix_Example_Plugin" or "My_Plugin"... This let suppose that there is a main class for the plugin.

Well, unless a plugin is made by one single class, in which case name it after plugin name is absolutely reasonable), to create a class that manage the entire plugin (e.g. adding all the hooks plugin needs or instantiating all the other plugin classes) can be considered a bad practice, as an example of god object.

In object oriented programming code should tend to be S.O.L.I.D. where the "S" stand for "Single responsibility principle".

It means that every class should do a single thing. In WordPress plugin development it means that developers should avoid to use a single hook to instantiate a main plugin class, but different hooks should be used to instantiate different classes, according to the class responsibility.

Avoid hooks in constructor

This argument has been introduced in other answers here, however I want to remark this concept and link this other answer where it has been pretty widely explained in the purview of unit testing.

Almost 2015: PHP 5.2 is for zombies

Since 14 August 2014, PHP 5.3 reached its end of life. It's definitely dead. PHP 5.4 is going to be supported for all 2015, it means for another year at the moment I'm writing.

However, WordPress still supports PHP 5.2, but no one should write a single line of code that support that version, especially if code is OOP.

There are different reasons:

  • PHP 5.2 dead a long time ago, no security fixes are released for it, that means it isn't secure
  • PHP 5.3 added a lot of features to PHP, anonymous functions and namespaces über alles
  • newer versions of PHP are a lot faster. PHP is free. Updating it is free. Why use a slower, unsecure version if you can use a faster, more secure one for free?

If you don't want to use PHP 5.4+ code, use at least 5.3+

Example

At this point is time to review older answers based on what I said until here.

Once we don't have to care about 5.2 anymore, we can and should, use namespaces.

For sake of better explain single responsibility principle, my example will take 3 classes, one that do something on frontend, one on backend and a third used in both cases.

Admin class:

namespace GM\WPSE\Example;

class AdminStuff {

   private $tools;

   function __construct( ToolsInterface $tools ) {
     $this->tools = $tools;
   }

   function setup() {
      // setup class, maybe add hooks
   }

}

Frontend class:

namespace GM\WPSE\Example;

class FrontStuff {

   private $tools;

   function __construct( ToolsInterface $tools ) {
     $this->tools = $tools;
   }

   function setup() {
      // setup class, maybe add hooks
   }

}

Tools interface:

namespace GM\WPSE\Example;

interface ToolsInterface {

   function doSomething();

}

And Tools class, used by other two:

namespace GM\WPSE\Example;

class Tools implements ToolsInterface {

   function doSomething() {
      return 'done';
   }

}

Having this classes, I can instantiate them using proper hook. Something like:

require_once plugin_dir_path( __FILE__ ) . 'src/ToolsInterface.php';
require_once plugin_dir_path( __FILE__ ) . 'src/Tools.php';

add_action( 'admin_init', function() {

   require_once plugin_dir_path( __FILE__ ) . 'src/AdminStuff.php';
   $tools = new GM\WPSE\Example\Tools;
   global $admin_stuff; // this is not ideal, reason is explained below
   $admin_stuff = new GM\WPSE\Example\AdminStuff( $tools ); 
} );

add_action( 'template_redirect', function() {

   require_once plugin_dir_path( __FILE__ ) . 'src/FrontStuff.php';
   $tools = new GM\WPSE\Example\Tools;
   global $front_stuff; // this is not ideal, reason is explained below
   $front_stuff = new GM\WPSE\Example\FrontStuff( $tools );    
} );

Dependency Inversion & Dependency Injection

In the example above I used namespaces and anonymous functions to instantiate different classes at different hooks, putting in practice what I said above.

Note how namespaces allow to create classes names without any prefix.

I applied another concept that was indirectly mentioned above: Dependency Injection, it is one method to apply Dependency Inversion Principle, the "D" in SOLID acronym.

The Tools class is "injected" in the other two classes when they are instantiated, in this way is possible to separate responsibility.

In addition, AdminStuff and FrontStuff classes use type hinting to declare they need a class that implements ToolsInterface.

In this way ourself or users that use our code may use different implementations of same interface, making our code not coupled to a concrete class but to an abstraction: that's exactly what Dependency Inversion Principle is about.

However, example above can be further improved. Let's see how.

Autoloader

A good way to write better readable OOP code is not to mix types (Interfaces, Classes) definition with other code, and to put every type in its own file.

This rule is also one of the PSR-1 coding standards1.

However, doing so, before being able to use a class one needs to require the file that contains it.

This can be overwhelming, but PHP provides utility functions to auto load a class when it is required, using a callback that load a file based on its name.

Using namespaces it becomes very easy, because is possible to match folders structure with namespace structure.

That's not only possible, but it is also another PSR standard (or better 2: PSR-0 now deprecated, and PSR-4).

Following that standards is possible make use of different tools that handle autoload, without having to code a custom autoloader.

I have to say that WordPress coding standards have different rules for naming files.

So when writing code for WordPress core, developers have to follow WP rules, but when writing custom code it's a developer choice, but using PSR standard is easier to use already written tools2.

Global Access, Registry and Service Locator Patterns.

One of the biggest issues when instantiating plugin classes in WordPress, is how to access them from various part of the code.

WordPress itself uses the global approach: variables are saved in global scope, making them accessible everywhere. Every WP developer type the word global thousands of times in their career.

This is also the approach I used for the example above, but it is evil.

This answer is already too much long to allow me to further explain why, but reading first results in the SERP for "global variables evil" it's a good starting point.

But how is possible to avoid global variables?

There are different ways.

Some of the older answers here use the static instance approach.

public static function instance() {

  if ( is_null( self::$instance ) ) {
    self::$instance = new self;
  }

  return self::$instance;
}

It's easy and pretty fine, but it forces to implement the pattern for every class we want to access.

Moreover, a lot of times this approach puts on the way to fall in the god class issue, because developers make accessible a main class using this method, and then use it to access all other classes.

I already explained how bad is god class, so static instance approach is a good way to go when plugin only need to make accessible one or two classes.

This not means that it can be used only for plugins having just a couple of classes, in facts, when the dependency injection principle is used properly, is possible to create pretty complex applications without the need to make globally accessible a large number of objects.

However, sometimes plugins need to make accessible some classes, and in that case the static instance approach is overwhelming.

Another possible approach is to use the registry pattern.

This is a very simple implementation of it:

namespace GM\WPSE\Example;

class Registry {

   private $storage = array();

   function add( $id, $class ) {
     $this->storage[$id] = $class;
   }

   function get( $id ) {
      return array_key_exists( $id, $this->storage ) ? $this->storage[$id] : NULL;
   }

}

Using this class is possible to store objects in the registry object by an id, so having access to registry it's possible to have access to all the objects. Of course when an object is created for first time it needs to be added in the registry.

Example:

global $registry;

if ( is_null( $registry->get( 'tools' ) ) ) {
  $tools = new GM\WPSE\Example\Tools;
  $registry->add( 'tools', $tools );
}

if ( is_null( $registry->get( 'front' ) ) ) {
  $front_stuff = new GM\WPSE\Example\FrontStuff( $registry->get( 'tools' ) );    
  $registry->add( 'front', front_stuff );
}

add_action( 'wp', array( $registry->get( 'front' ), 'wp' ) );

Example above make clear that to be useful the registry need to be globally accessible. A global variable for the sole registry is not very bad, however for non-global purists is possible implement the static instance approach to registry, or maybe a function with a static variable:

function gm_wpse_example_registry() {
  static $registry = NULL;
  if ( is_null( $registry ) ) {
    $registry = new GM\WPSE\Example\Registry;
  }
  return $registry;
}

First time function is called it will instantiate the registry, on subsequent calls will just return it.

Another WordPress-specific method to make a class globally accessible is returning an object instance from a filter. Something like this:

$registry = new GM\WPSE\Example\Registry;

add_filter( 'gm_wpse_example_registry', function() use( $registry ) {
  return $registry;
} );

After that everywhere the registry is needed:

$registry = apply_filters( 'gm_wpse_example_registry', NULL );

Another pattern that can be used is the service locator pattern. It's similar to registry pattern, but service locators are passed to various classes using dependency injection.

Main problem with this pattern is that it hides classes dependencies making code harder to maintain and to read.

DI Containers

No matter the method used to make registry or service locator globally accessible, objects have to be stored there, and before to be stored they need to be instantiated.

In complex applications, where there are quite a lot classes and many of them have several dependencies, instantiate classes require a lot of code, so possibility of bugs increases: code that doesn't exist can't have bugs.

In last years appeared some PHP libraries that help PHP developers to easily instantiate and store instance of objects, automatically resolving their dependencies.

This libraries are known as Dependency Injection Containers because they are capable to instantiate classes resolving dependencies and also to store objects and return them when needed, acting similarly to a registry object.

Usually, when using DI containers, developer have to setup the dependencies for every class of the application, and then first time a class is needed in the code it is instantiated with proper dependencies and same instance is returned again and again on subsequent requests.

Some DI containers are also capable to automatically discover dependencies without configuration, but using PHP reflection.

Some well known DI Containers are:

and many others.

I want to point out that for simple plugins, that involves only few classes and classes have not many dependencies, probably it doesn't worth to use DI containers: the static instance method or a global accessible registry are good solutions, but for complex plugins benefit of a DI container becomes evident.

Of course, even DI container objects have to be accessible to be used in the application and for that purpose is possible use one of the method seen above, global variable, static instance variable, returning object via filter and so on.

Composer

To use DI container often means use 3rd party code. Nowadays, in PHP, when we need to use an external lib (so not only DI containers, but any code that isn't part of the application), simply download it and put in our application folder is not considered a good practice. Even if we are the authors of that other piece of code.

Decoupling an application code from external dependencies is symptom of better organization, better reliability and better sanity of the code.

Composer, is de-facto standard in PHP community to manage PHP dependencies. Far away to be mainstream in WP community as well, it's a tool that every PHP and WordPress developer should at least know, if not use.

This answer is already book-sized to allow further discussion, and also discussing Composer here is probably off topic, it was only mentioned for sake of completeness.

For more informations visit Composer site and also it worth give a read to this minisite curated by @Rarst.


1 PSR are PHP standards rules released by PHP Framework Interop Group

2 Composer (a library that will be mentioned in this answer) among other things also contain an autoloader utility.

share|improve this answer
1  
An additional note, that PHP 5.3 is also end of life. A responsible host will offer at least 5.4 as an option if not a default –  Tom J Nowell Oct 27 at 10:55
    
"Since 14 August 2014, PHP 5.3 reached its end of life. It's definitely dead." Is the first line under "PHP 5.2 is for zombies" @TomJNowell –  G. M. Oct 27 at 11:50

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
3  
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

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

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.