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();
  • 1
    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.
    – Adam
    Commented Oct 23, 2012 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
    Commented Oct 24, 2012 at 8:40

5 Answers 5


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


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!
  • what would be the difference between add_action('plugins_loaded',...); and add_action('load-plugins.php',...); The example I took used the latter
    – kalpaitch
    Commented Oct 22, 2012 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.
    – Adam
    Commented Oct 22, 2012 at 10:00
  • 4
    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
    Commented Oct 23, 2012 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
    Commented Oct 31, 2012 at 9:52
  • 1
    As additional information, see this post from @mikeschinkel and the dicuss in the comments. hardcorewp.com/2012/…
    – bueltge
    Commented Jan 3, 2013 at 11:24

Arriving here exactly 2 years after the 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 isn't 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 it allows to instantiate plugin classes only when needed.

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

Generally speaking it 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 examples in older answers use a class named like "Prefix_Example_Plugin" or "My_Plugin"... This indicates that there probably is a main class for the plugin.

Well, unless a plugin is made by one single class (in which case naming it after plugin name is absolutely reasonable), to create a class that manages the entire plugin (e.g. adding all the hooks a plugin needs or instantiating all the other plugin classes) can be considered a bad practice, as an example of a 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, insecure 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+


At this point it 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 the single responsibility principle, my example will use 3 classes, one that does something on the frontend, one on the 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 a Tools class, used by the other two:

namespace GM\WPSE\Example;

class Tools implements ToolsInterface {

   function doSomething() {
      return 'done';


Having this classes, I can instantiate them using proper hooks. 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 named 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, so in this way it 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 ourselves or users that use our code may use different implementations of the 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, the example above can be further improved. Let's see how.


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 loads a file based on its name.

Using namespaces it becomes very easy, because now it is possible to match the folder structure with the 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 it is possible to 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 parts of the code.

WordPress itself uses the global approach: variables are saved in global scope, making them accessible everywhere. Every WP developer types 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 much too long to allow me to further explain why, but reading the first results in the SERP for "global variables evil" is a good starting point.

But how is it 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 a god class is, so the static instance approach is a good way to go when a plugin only needs to make accessible one or two classes.

This doesn't mean that it can be used only for plugins having just a couple of classes, in fact, when the dependency injection principle is used properly, it 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 it is possible to store objects in the registry object by an id, so having access to a registry it's possible to have access to all the objects. Of course when an object is created for the first time it needs to be added to the registry.


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' ) );

The example above makes clear that to be useful the registry needs to be globally accessible. A global variable for the sole registry is not very bad, however for non-global purists it is possible to implement the static instance approach for a 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;

The first time the function is called it will instantiate the registry, on subsequent calls it 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 the 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 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, instantiating classes requires a lot of code, so the possibility of bugs increases: code that doesn't exist can't have bugs.

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

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

Usually, when using DI containers, developers have to setup the dependencies for every class of the application, and then the first time a class is needed in the code it is instantiated with proper dependencies and the 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 involve 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 the 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 it is possible to use one of the methods seen above, global variable, static instance variable, returning object via filter and so on.


To use DI container often means using 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 downloading it and putting it 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 sign of better organization, better reliability and better sanity of the code.

Composer, is the 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 information visit the Composer site and it's also worth giving a read to this minisite curated by @Rarst.

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

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

  • 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
    Commented Oct 27, 2014 at 10:55
  • 2
    "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
    – gmazzap
    Commented Oct 27, 2014 at 11:50
  • 3
    Just wondering, what would you pointing out a "lot of things" look like? ;-) Commented Dec 25, 2015 at 9:15
  • In efforts to avoid global variables, I like the idea of the Registry pattern with function & static variable. The first time the function is called it will instantiate the registry, on subsequent calls it will just return it. Commented Aug 11, 2017 at 16:00
  • Biggest problem with registry is that, this creates a mess of variables and typos can cause a lot of problems. If you are using predefined classes, then all modern IDE's will provide to you overview of class properties etc and you can easily choose the right one. Arrays are one of the worst variables as they cause a lot of problems. The most common error I see on WordPress plugins is "undefined index". Using classes makes sure that all your properties are defined whenever you need them. Registries lead to the more dirty and faulty architecture.
    – D.A.H
    Commented May 20, 2021 at 8:47

I use following structure:


 * 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(  ) {



  • 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.

  • 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
    – Adam
    Commented Oct 22, 2012 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? Commented May 28, 2013 at 5:52
  • 1
    @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
    Commented May 28, 2013 at 10:35
  • Neat idea, but can be used on plugin main class only. The one of biggest problem of many WordPress plugin is that they load tons of code which is never used for request. To avoid loading tons of actually not used code, you have to split your functionality into smaller chunks by using namespaces and classes and then to use autoload, which loads only these files, which are actually used. This kind of approach requires more careful development of plugin, to make sure that you have request based logic (code is used always for one request and dies after that).
    – D.A.H
    Commented May 20, 2021 at 8:21

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.

  • 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
    Commented Oct 22, 2012 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.
    Commented Oct 22, 2012 at 9:54

I know this is a couple years old, but meanwhile php 5.3 supports anonymous methods, so I came up with this:

add_action( 'plugins_loaded', function() { new My_Plugin(); } );

and somehow I like it the most. I can use regular constructors and don't need to define any "init" or "on_load" methods that mess up my OOP structures.

  • You can use both, anonymous functions and anonymous classes too. So you can use anonymous classes if your class serves limited tasks and you don't have to serialise it.
    – D.A.H
    Commented May 20, 2021 at 8:24

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.