Singletons in PHP

Or...bad PHP programming practices. [Update: 3/18/2015]
Series: 
Object Oriented PHP in Plain English

Introduction…or a mini-rant.

So, over the past few weeks, I've been interviewing for a number of PHP programming positions, and have been consistently asked "What is a Singleton?". I've consistently replied "A programming construct which has no place in the share-nothing world of PHP." Just a quick note, that is the right answer, if not descriptive of what a Singleton actually is. To the three potential employers who retorted that I was wrong, I'd like to point you to a more persuasive argument on Why Singletons have no use in PHP by Gordon Oheim, (aka gooh), a Zend Certified programmer. Many of his very valid points are reiterated here, because while I don't currently share Herr Oheim's certification, I certainly share his conviction on the topic. The intent of this article is simply to address the two most common misconceptions about Singletons in PHP.

So, What is a Singleton?

I'll point you to Wikipedia for the full blown definition of a Singleton. In it's most simple form, a Singleton is a programming design pattern that ensures a single instance of a class across an application. Singletons are often useful (in other languages) for limiting the number of connections to a database or limiting the amount of memory a particular instance of a class can take up.  A Singleton is very easy to write. All it requires, at it's most basic, is a class with a static instance variable and the Singleton method within that class. A very concise example of using Singletons in PHP can be found on WebGeekly.com, from which I've borrowed the example below.

<?php
class User
{
    // Hold an instance of the class
    private static $instance;
 
    // The singleton method
    public static function singleton()
    {
        if (!isset(self::$instance)) {
            self::$instance = new __CLASS__;
        }
        return self::$instance;
    }
}
?>

Now to create the object:

$oUser1 = User::singleton(); 
$oUser2 = $oUser1; 
$oUser3 = &$oUser1;

All three variables here will point to the same object. The first call creates the instance. The subsequent calls, only return references the instance created by the first call - remember, in PHP 5+, all objects are passed by reference. That is to say, unless you instantiate an instance of a class via the `new` keyword or `clone` a copy of an existing class, you're most likely dealing with a reference...which leads me to admit that a Singleton in PHP sounds like a very tempting design pattern, however, it is deceptive - like the unicorn! (The mythical creature, not the rapist bit....)

​Argument 1: Limiting Instances of a Class

PHP is, as I mentioned before, based on a "Share Nothing" architecture. This basically means that data, in our case, class instances, isn't shared between separate PHP processes. To further drive home this understanding, let's talk about PHP in it's most commonly understood usage: the web world.

Timmy and Tammy are using your web application, for our simplified purposes, in perfect tandem. Timmy's requests and Tammy's requests are, exactly the same, issued at exactly the same time, received at the same time and processed at the same time. No matter how you break it down, Timmy and Tammy's requests are handled in separate PHP processes. We'll widen our example to say that your web application utilizes the Singleton pattern for handling database requests. When PHP is dealing with Timmy's request, the Singleton for his database connection is created and available to his PHP process only. Tammy's request's Singleton is available for her request only. Congratulations, you've just created two instances of the same class within the same application.

As you see in the example in the definition above, it's enticing to think "Oh boy, every time a new user instance is created, it's just referring to that already created user instance." That's not the case, and the example above is bad programming, in my humble opinion. Working in an Object Oriented Programming language, you should be conscientious of why you're creating an instance of an object; specifically what purpose it serves. If you need a more "flexible" object, consider working with Dependency Injection or Factory Pattern. Here I'm going point you to two examples of the Factory Pattern. The first is WebGeekly.com's Factory Pattern post where you may notice that the Factory Pattern bears a resemblance to the Singleton Pattern, but without the instance limiter. The power behind it, however, can be seen in this much fuller example on the Factory Pattern DevShed post. The long and the short of the Factory Pattern is that you build your classes flexibly, so if you need to return a different data type or format down the road, it can be done by manipulating the existing class, rather than creating a new instance. Which...kinda sounds like the best of both the Dependency Injection pattern and the Singleton pattern, but that's just me.

Argument 2: Limiting Resource Usage

Yes, I really should call this a sub-argument of the last argument, but this is what all three potential employers threw back at me as their definitive answer on Singleton usage, so I've separated it out into it's own argument. Because of the deceptive appearance of the Singleton in PHP, an assumption is made that fewer CPU cycles will have to run to generate the new class instance and less memory, overall, will be used when a Singleton class is instantiated. This is just not true. Paying attention to the example in the definition above, I posit the question, "Why do you need three variables which point to the same object?" The class instances were created in the same way, so the object is exactly the same - why not just re-use the first variable? Paying attention to the "Timmy and Tammy" example above, we see that no real gain is made across processes, because of the Share Nothing architecture.

Here's my super simplified example:

$a = 1; 
$b =& $a; 
$c =& $b;
...
$x =& $w;
$z =& $y; 

If $a is manipulated in any way, $b - $z's values are also automatically updated, because they're references. By creating references to the Singleton object, you're actually cluttering memory with useless references and taking up more CPU cycles to follow the referential paths.

Conclusion

These are just my humble opinions. There are literally dozens of other reasons not to use Singletons in PHP (the inability to serialize the object being a main reason I didn't touch on here). I hope someone will prove me wrong in the future, or that PHP's architecture will catch up with other programming languages to a point where the use of the Singleton is an effective design pattern. It's just not, now.

Update: 3/18/15 - 3 1/2 years later.

Someone has proven me wrong in the most absolutely fantastic way - twice in seven days. Well, two different teams of someones working on projects that have taken each of them roughly that long each to reach their goals. The first team, can't say who it is, has found a maddeningly simple mechanism for creating a linux service from a PHP FCGI instance, whose only job it is to handle singleton connection to a database so that it doesn't get clobbered. Going around your a** to get to your elbow? (Or is it the other way 'round?) Yes. Strictly necessary in their environment? Yeah, kinda maybe. They have megaflops (or something REAL BIG) of processing power and gigapetafiles of space...probably not...and no, I'm not telling you who they are in case..well...they end up on my resume :P

On the flip side, and it may just be my inner geek, crying for a use for this wonderfully unavailable little idea: AppServer.io has developed a PHP application server that has servlet containers...built on....singletons - at least that's what I got from the doc. I haven't even finished the git clone as I type furiously...it's taken three and a half years, and I basically unearthed both of the unwitting challengers myself, but - Singletons, in PHP, folks! Love it!