Home » PHP » PHP Tutorial: The Legend of the Singleton

PHP Tutorial: The Legend of the Singleton

I'm enjoying this experiment in explaining design patterns through storytelling, so today's is the Singleton Pattern.

Long, long ago and far, far away, a king commissioned all his wizards to create a single repository of all the kingdom's knowledge. In the kingdom's language, their word for knowledge was "data" and this repository was supposed to form the base of all knowledge, so they called it the Great Database. It took the form of a giant bucket in which all the kingdom's knowledge was stored as a pool of information, and it was levitated over the sands of the Great Desert.

To use the Great Database, one would throw a large hose up over the rim of the tub to connect with the pool. They could then add to, retrieve, or even update the knowledge in the pool. In early tests, the magicians made this work flawlessly and the king was overjoyed at his Great Database. He threw a great party to celebrate its creation.

Every school in the kingdom was invited to send one class. Many classes wanted to use the Great Database, but when all their members each threw up a hose, the great weight of so many connections brought the Great Database crashing down. The magicians were called and worked furiously to detach all the hoses and raise the Great Database once more.

To solve this problem of too many hoses, they limited each class to one hose and appointed one member the keeper of the hose. But some classes took a long time to complete all their members' queries of the Great Database because they would throw up the hose before each question and then pull it down after, wasting time and tiring their keeper of the hose. And every time a new class came along, the magicians had to spend time training one of its members in casting and retrieving the hose.

Finally, Ignatz the Fetid conceived of an idea... a single hose. It would be cast by a worker who would manage it and bring it to each class when requested. When no classes needed it, it could be disconnected, but when called by a class, it would be left connected until all the classes' sessions were done and they were cleared.

Because it had to do much work and was rather large, this hose was very heavy. It weighed exactly 2,000 pounds. Since it did not weigh more or less, it was declared that it weighed a "single ton," and that became its name. Over the years, the words ran together and today we know it as the Singleton.

The Singleton pattern is a simple form of resource management. Every time you create a resource like a database handle or a filestream, there's a cost in overhead. If you create multiple, you create more overhead. And whenever you release one before you're done, then have to re-establish it, the repetition slows down execution.

So we create a class that manages that resource. Whenever another class requests the resource, the class checks to see if it exists, and if not, it creates it. Then, until execution ends, every class that needs the resource gets it passed to them instead of getting a new one created. By sharing the resource through this manager, the cost of redundant resources or repeated creation/release of resources is mostly eliminated.

Here's a simple singleton:

class Database{

    private static $instance;
    private $db;

    private function __construct(){
        /**
         *Create the database connection
         */
        [database connection information]
        $this->db = mysql_connect($dbserver, 
           $userdbl, $userdba) or die("could not connect to database");
        mysql_select_db([name of db],$this->db);
    }

    public static function getInstance(){
	if(!self::$instance){
	    self::$instance = new Database();
        }
        return self::$instance;
    }
}

Now this isn't quite the same as in the IBM article. I saw this way of implementing a singleton in another article and liked the idea of making the __construct() method private. That way, no one can instantiate the Database class as an object except the class itself. And because you're passing the Database object instead of simply passing the database connection handle, you can implement some ORM as methods in the object.

Anyhow, I hope you enjoyed this. If you did, please leave a comment, tweet about it, or link to it from your favorite mailing list or social media site.

9 Responses to PHP Tutorial: The Legend of the Singleton

  1. This was a great article and I very much enjoyed it! Thanks for the illustration.

  2. Single Ton .. haha... very clever.

  3. Very interesting and useful, thanks.

  4. Nice story, good job! Maybe it would be useful to mention that singleton is considered to be an anti-pattern. It might not be the best idea to overuse it. For example it's just a hidden global variable and we know globals are evil:)

  5. Thanks, very interesting and simple stories. Waiting for the next one.

  6. Usually you need to block clone and wakeup in PHP when using singleton. (If someone clone your singleton it's not a singleton anymore.)


    /**
    * Cloning is blocked because of the singleton pattern.
    */
    public function __clone() {
    trigger_error('Clone is not allowed.', E_USER_ERROR);
    }

    /**
    * Wakeup is blocked because of the singleton pattern.
    */
    public function __wakeup() {
    trigger_error('Unserializing is not allowed.', E_USER_ERROR);
    }

    Also I suggest you to write some words when not to use the singleton pattern, because it's one of the most missused patterns.

  7. Another excellent post. Thanks!

  8. [...] PHP Tutorial: The Legend of the Singleton | PHP Tip A Day [...]

  9. Hey, just wanted to say loving the pattern allegories. Keep it up.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>