After one of our earlier posts Eric Mann whose opinion we highly respect initiated a conversation with me over Twitter's DM where he expressed a dislike for the HardcoreWP approach and stated a preference for using ::get_instance() instead:

  1. public static function get_instance() {
  2.   if ( ! isset( self::$_this ) ) {
  3.     self::$_instance = new self;
  4.   }
  5.   return self::$_instance;
  6. }
public static function get_instance() {
  if ( ! isset( self::$_this ) ) {
    self::$_instance = new self;
  }
  return self::$_instance;
}

While this approach is perfectly workable and truth be told it's mostly just personal preference we still like our approach better, read on.

Lazy Initialization

After much discussion we recognized that ::get_instance() as implemented in a Singleton was using what Wikipedia refers to as Lazy initialization. Here's what it would look like if we modified our ongoing "Thanks for Reading plugin" example to apply this approach:

  1. <?php
  2. /*
  3.  * Plugin Name: Thanks for Reading
  4.  */
  5. class Thanks_For_Reading_Plugin {
  6.   private static $_instance;
  7.   public static function get_instance() {
  8.     if ( ! isset( self::$_instance ) ) {
  9.       self::$_instance = new self;
  10.     }
  11.     return self::$_instance;
  12.   }
  13.   function __construct() {
  14.     add_filter( 'the_content', array( $this, 'the_content' ) );
  15.   }
  16.   function the_content( $content ) {
  17.     return $content . '<p>Thanks for Reading!</p>';
  18.   }
  19. }
  20. $thanks_for_reading = Thanks_For_Reading_Plugin::get_instance();
<?php
/*
 * Plugin Name: Thanks for Reading
 */
class Thanks_For_Reading_Plugin {
  private static $_instance;
  public static function get_instance() {
    if ( ! isset( self::$_instance ) ) {
      self::$_instance = new self;
    }
    return self::$_instance;
  }
  function __construct() {
    add_filter( 'the_content', array( $this, 'the_content' ) );
  }
  function the_content( $content ) {
    return $content . '<p>Thanks for Reading!</p>';
  }
}
$thanks_for_reading = Thanks_For_Reading_Plugin::get_instance();

Eric has even written three (3) recent posts advocating (lazy-initialized) Singletons for use in WordPress plugins.

Eager Initialization

The alternate to Lazy initialization is referred to as Eager initialization and that is what we recommend for the main class of a plugin here at HardcoreWP. This approach creates an instance early in page load which means we don't have to check for isset( self::$_this ) on every instance access:

  1. <?php
  2. /*
  3.  * Plugin Name: Thanks for Reading
  4.  */
  5. class Thanks_For_Reading_Plugin {
  6.   private static $_this;
  7.   function __construct() {
  8.     if ( isset( self::$_this ) )
  9.       wp_die( sprintf( __( '%s is a singleton class and you cannot create a second instance.',
  10.         'thanks-for-reading' ), get_class( $this ) ) );
  11.  
  12.     self::$_this = $this;
  13.     add_filter( 'the_content', array( $this, 'the_content' ) );
  14.   }
  15.   static function this() {
  16.     return self::$_this;
  17.   }
  18.   function the_content( $content ) {
  19.     return $content . '<p>Thanks for Reading!</p>';
  20.   }
  21. }
  22. new Thanks_For_Reading_Plugin();
<?php
/*
 * Plugin Name: Thanks for Reading
 */
class Thanks_For_Reading_Plugin {
  private static $_this;
  function __construct() {
    if ( isset( self::$_this ) )
      wp_die( sprintf( __( '%s is a singleton class and you cannot create a second instance.',
        'thanks-for-reading' ), get_class( $this ) ) );

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

An added benefit is we don't leave a variable lying around in the global namespace, although the Lazy approach does not actually require the global it just seems to be a common practice when using Lazy initialization.

Comparing the Pros and Cons

Let's compare the pros and cons:

  • Lazy initialization

    • PROs: Doesn't create an instance until it's needed potentially improving performance and saving memory.
    • CONs: Performs an isset() check on every instance access.
  • Eager initialization

    • PROs: Doesn't Performs an isset() check on every instance access.
    • CONs: Always creates an instance even if it's not needed potentially degrading performance and wasting memory.

Effectively the PROs of each approach are the CONs of the other. So which matters more?

Delayed Initialization Not a Benefit for our Use-Case

The Lazy initialization approach waits to create an instance until it's needed but since we are using the singleton class to hook actions and filters for a WordPress plugin we will always need to instantiate it early during page load. This means the benefits of lazy initialization are moot for our use-case.

Is Checking on Every Instance Access Really Necessary?

On the con side the Lazy approach evaluates the ! isset( self::$_instance ) expression on every object access. And while the check is not very expensive it's potentially made many times. Why not do eliminate this check if everything else is equal?

Which to Use?

Clearly either approach is better than using globally scoped functions for plugin hooks. But since the benefits of Lazy initialization are moot for our use-case we choose Eager initialization[^singleton-use-cases] approach for since it has a tiny extra benefit.

And Eric?

As we said before, we have great respect for Eric Mann, this post is not meant to be a knock on him. Eric has made a tremendous contribution over at StackExchange's WordPress Answers and his answers are always top-notch. We just happen to prefer our approach to implementing a Singleton for the main class used for a WordPress plugin over his. And given we are both opinionated developers, would you expect any less? 🙂

What's your Take?

That said, got a contrary opinion too? Let us know in the comments below.

[footnotes]
[^singleton-use-cases]: But is Eager the best approach for all Singleton use-cases? Certainly not. If a Singleton is not always instantiated for every page load then the Lazy approach of using ::get_instance() is probably the better of the two. But that would call the question "Is the Singleton pattern really appropriate for this other use-case?" And to answer that question is beyond the scope of this post. What's more, we're not even sure it's a question we want to get in the middle of. At least not unless we discover that the question relates directly to WordPress plugin development which at this point we don't think it does. 🙂
[/footnotes]

9 thoughts on “Initializing Singleton Classes used in WordPress Plugins

  1. One disadvantage of using singletons I’ve read about is that it prevents unit tests from creating new instances without activating any hooks automatically. Actually, I don’t think it’s a disadvantage of singletons really, but just of not having an empty constructor. Check out the empty constructor approach. (I have to admit, though, that I’m not at the point yet where I write unit tests for my WP plugins.)

    Back to the difference between lazy and eager initialization, do you really see the extra isset() check as a disadvantage of lazy initialization? I’d think the impact on performance of such a check is totally neglectable. Sure the check is not needed for the main class of the plugin since it will always be instantiated, as you mentioned, but that may not be the case for other classes used in a plugin. I’d prefer some consistency then and use a static get_instance() method in every class then. Well, I guess you could simply rename the this() method also while still keeping the eager initialization for the main class of the plugin.

    Definitely an interesting read. Great blog! Thanks, Mike.

    Reply
    • Hi @Geert,

      Thanks for the comments! Yes, there are issues with Singletons and unit tests, but the use-case for which we are using Singletons make unit-testing concerns irrelevant. You can’t do classical unit-testing of the series of WordPress hooks that a plugin needs to use, you have to do HTTP GET or POST request testing instead. Note my footnote where I explicitly say what use-case I’m addressing. So the unit-testing issue is moot here, and one I’ve actually got a half-written post planning to address in the near future.

      As for the empty constructor approach linked to @toschos Gist, it just so happens my next post will be introducing that approach, but with a few important improvements.

      As for the isset() check, you are correct it’s not that big of a benefit but I see absolutely no benefit to the Lazy initialization approach for this use-case so I prefer not to use the Lazy approach. Besides, the Lazy approach makes more difficult some things I plan to blog about later so I’m really just trying to steer things in the right direction for future posts.

      As for other classes in the plugin, to be clear I’m recommending Singletons explicitly for the plugin classes designed to encapsulate hook methods and I’ve tried to emphasize that in many peoples including in the footnote. So yes I agree, for other use-cases Lazy initialization makes more sense, with a caveat.

      The caveat is I’ve yet to come across another valid use-case for a Singleton within a WordPress plugin, so I’m wondering is that isn’t moot point too. Note I’m not saying there is not another good reason to use one, I’ve just thus far not discovered another good use-case (well except for class to encapsulate hooks for a theme, but that’s pretty much the same use-case as for plugins anyway.)

      As for ::get_instance() vs. ::this() my personal preference is (obviously) to use this latter and the reason is 1.) the former is really long which makes using it more cumbersome than it needs to be:

      My_Plugin_Classname::get_instance()->my_long_method_name();

      Compared to this which isn’t quite as bad:

      My_Plugin_Classname::this()->my_long_method_name();

      Length matters if you are doing if( expression1 and expression2 ) or if you are doing for( expression as $variable ), and so on.

      Also ::this() is really a special case method so I’d prefer to use a special case method name. I prefer it over names I might use for property accessor methods like ::get_title() or ::get_menu() etc. In other words I’d rather not use the same function naming pattern I use to access properties of the object vs. the object itself.

      On a side note, I really wish PHP would allow us to declare a class with a singleton modifier and then let us access the instance like so:

      // Accesses the my_long_method_name() of the Singleton instance for this class
      My_Plugin_Classname->my_long_method_name();
      
      // Retrieves the Singleton instance for this class
      $object = My_Plugin_Classname;

      But alas, they don’t!

      Anyway, thanks for the kind comments. I’ve got a lot more planned; I hope I can continue to keep it interesting. 🙂 More importantly I hope I can make it useful!

      Reply
  2. Well you can do unit-testing for your plugins, but you need to shield a lot from the WP-side, that’s true. Anyway, I’d say this is preference and it’s common to not Unit-Test because the Unit-Tests in the WordPress testsuite are very limited anyway and this is not much of an incentive to do that for your own code. So you should name the problem properly: Most plugin authors are not invited to Unit-Test, so it’s no wonder many aren’t doing any tests. Just to put it into the right light.

    In one of my previous posts I’ve highlighted something similar, not a singleton, but a factory, it’s in form of an answer on Stackoverfow: WordPress Plugin: How do I avoid “tight coupling”? – http://stackoverflow.com/a/8688954/367456 – Actually apart from eager or lazy loading, you don’t need to design your plugin as a singleton. The main plugin class can just be a standard class, what you actually have here is creating the plugin class instance.

    BTW the question about lazy or eager is not really one here. If you see both code examples, both are instantiated immediately when the plugin file is required.

    So practically neither of you is doing lazy initialization. Both are doing eager initialization, for the concrete request, it’s not known if the plugins functionality will be used or not, however it’s always instantiated.

    Some form of lazy initializatioin I know for WordPress plugins works therefore a little different. For example many larger plugins have some administrative interface. But most request to WP are frontend, so loading the administration part is useless often. It will be “lazily loaded” (read: require(__DIR__ . ‘/admin.php’); or similar) only if the request is dedicated towards the admin interface (and the request is actually done by a verified user).

    Similar for AJAX handlers.

    So look carefully if there really is a benefit. I’d say, Singleton or not is useless here. You don’t need to create singletons for your plugin classes. As it’s superfluous, it can only stand in your own way after some time (as written, for testing, but also for easily extending and maintaining the code).

    The other problem – I highlighted that as well with my factory and I properly should change the code as it’s also not really needed – is the static variable. It’s more conform with WordPress to refer the more common global variables here. This btw. will also ensure the “Singleton”-ness, because a global variable can only exist once with the same name.

    And for the plugin instance? Well, it has $this to refer to itself. Use it 😉 Just removing the fuzz about singletons and static variables normally makes the code more fluent and will allow more easily a true lazy loading because classes work more independently.

    Reply
    • Hi @hakre,

      Thanks for taking the time to stop by and make a great comment.

      In one of my previous posts I’ve highlighted something similar, not a singleton, but a factory, it’s in form of an answer on Stack Overflow: WordPress Plugin: How do I avoid “tight coupling?” Actually apart from eager or lazy loading, you don’t need to design your plugin as a singleton. The main plugin class can just be a standard class, what you actually have here is creating the plugin class instance.

      You are absolutely correct, there are several different ways to architect code for a WordPress plugin. The approach we've advocated here is simply the one we've found to work the best for our plugin development work over the past several years. The approach you've posted similarly works well for you too, I'm sure.

      BTW the question about lazy or eager is not really one here. …both are instantiated immediately when the plugin file is required. So practically neither of you is doing lazy initialization.

      Again you are completely correct; what I've shown above is actually not Lazy initialization. What it is instead is using the class pattern required for Lazy initialization but then initializing it immediately. Hopefully my commenting here to that effect will be sufficient for readers who might be confused.

      Some form of lazy initialization I know for WordPress plugins works therefore a little different. For example many larger plugins have some administrative interface. But most request to WP are frontend, so loading the administration part is useless often. It will be "lazily loaded" (read: require(__DIR__.'/admin.php'); or similar) only if the request is dedicated towards the admin interface (and the request is actually done by a verified user). .. Similar for AJAX handlers.

      Yet again I agree.

      So look carefully if there really is a benefit. I’d say, Singleton or not is useless here. You don’t need to create singletons for your plugin classes. As it’s superfluous, it can only stand in your own way after some time (as written, for testing, but also for easily extending and maintaining the code).

      On this we disagree. Minimally the benefits include simplicity and clear code. And the use-cases for which I'm using the Singleton doesn't have the downsides you imply.

      The other problem – I highlighted that as well with my factory and I properly should change the code as it’s also not really needed – is the static variable. It’s more conform with WordPress to refer the more common global variables here. This btw will also ensure the “Singleton”-ness, because a global variable can only exist once with the same name.

      For this I did not understand your point.

      And for the plugin instance? Well, it has $this to refer to itself. Use it Just removing the fuzz about singletons and static variables normally makes the code more fluent and will allow more easily a true lazy loading because classes work more independently.

      I'm not sure how someone would use $this outside of a class?

      Further, I held off replying to your comment for several days because I wanted to fully pondered your Factory example. I'm a fan of the Factory pattern and I use it frequently but it adds significant complexity so I only use where the benefits outweigh the complexity. As of yet I've seen no benefit to using a Factory for classes whose purpose is to encapsulate class methods used for hooks.

      Consider the majority use-case for plugins; you need one main class and the Singleton pattern is perfect for that class. If you add a Factory to it now you have two classes where the first instantiates the second and then the second hook the methods, but for what benefit? All I see is more complexity. Plugins being independent packages of code means you can't easily share the Factory across plugins; if you could — i.e. if the Factory were built into WordPress core — then it might be a different debate.

      Further we are talking about WordPress not Symphony or clean-room PHP. By it's very nature the "WordPress-ish" way is to favor simplicity rather than YAGNI complexity where most benefits are only found in edge-cases uncommon to WordPress.

      You mention the admin-only use-case; in that situation you simply use if ( ! is_admin() ) return; at the top of the file before the class is instantiated. And if you have a really large plugin you break it up into two or three Singleton classes; one for the front end, one for the admin and the third for AJAX.

      However, if you are building a plugin and come across the need for actual object instances then by all means create non-Singleton classes for those objects. My projects have many more non-Singleton classes than they do Singleton classes. But keep the main plugin class a Singleton.

      Anyway, many aspects of code architecture are personal preference, some aspects are important in some use-cases but not relevant in others and then there are the third set of aspects that really are critical. I think what we've discussed fits into the first category but if not at least the second but not the third. Whatever the case if you feel strongly about this particular topic I encourage you to blog about it yourself and if so I look forward to reading it as I think you know I'm subscribed. Hopefully I'll learn something new I've not previously discovered.

      Reply
  3. Just want you know there is a warning message on your homepage:

    Warning: Invalid argument supplied for foreach() in
    /home/hardcore/public_html/wp-content/themes/hardcorewp/functions.php on line 37

    Reply
    • Hi @Janek,

      Wow, that’s embarrassing and thanks for letting me know.

      I just added a new shortcode to the site and I evidently had a bug that I had not yet discovered. I think I’ve resolved it but will need more testing to be sure.

      Your comment makes me realize that rather than HardcoreWP being a rock solid site that never breaks we’re instead running a cutting edge site that is likely to spit out errors and warnings frequently. We are pushing the envelope a bit as we build new features and we’ll probably deploy them before they are rigorously tested in all knowable use-cases. We do a much better job of testing codes for our clients, but who has the same time to test code as rigorously for oneself? 🙂

      Ah well. I just hope we don’t end up with too many of these error messages too often.

      Reply
  4. How does this extend to larger plugins where you might have more complex, and lots more functionality?

    Say you were creating several post types, taxonomies and shortcodes. Usually these might be split into their own distinct class files, extending the base class.

    Reply
    • Hi @Tom,

      Thanks for the question.

      Yes it does apply to larger plugins, however that does not mean I’m advocating Singletions them for uses where class instances make more sense which is what it seems your takeaway from reading the post was. If so, my writing gave you the wrong impression. The use-case for Singletons is very narrow, but in the case of a WordPress plugin you’d use them for the first class you create.

      Beyond the narrow use-case for a Singleton, I have a library for creating plugins where I have instance classes for admin pages, admin tabs, forms, fields, shortcodes and external APIs but only one class for a Singleton; the main class. Does that answer?

      Reply
  5. Pingback: WordPress Tutoria | Annotary

Leave a reply

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" extra=""> 

required