Hi guys
A really short one today, just because someone asked me about it a couple of days ago. I also though it potentially best to avoid something as controversial as my last post about Eloquent and the Single Responsibility Principle, which caused a bit of a stir during the week.
So, you want to make sure you only ever use one specific instance of a class (maybe a DB connection) and need a quick and easy way to do it. Personally, this is the technique I would use:
<?php class MySingleton{ // This will hold the instance of the class private static $instance = null; // Declare this as private to stop anybody being able to use the "new" keyword private function __construct() { // Your usual constructor stuff in here } // This is where you get your instance public static function getInstance() { if(is_null(self::$instance)){ self::$instance = new self(); } return self::$instance; } }
All we’re doing here really, in a set of steps:
- You need a way to hold an instance of the object which is persistent throughout the execution
This is what the private static $instance is doing - You don’t want anybody to be able to directly use the new keyword, because then you’ve lost control of the instances of the object
- You need to be able to get an instance of the class, which is what the getInstance method is for
- In getInstance all we’re doing is instantiating the object if one hasn’t get been stored against the $instance static
So, to fetch your instance is simply:
$singleton = MySingleton::getInstance();
Wherever you run that throughout your code you will receive the exact same instance. Particularly useful in things like Database connections, loggers/debuggers and things like that.
Disclaimer: Don’t use singletons unless you’ve got a really good reason to
Note: It would appear that this topic is no less controversial than my last
General issue: missing a private __clone method, without that the instance can be cloned, therefore the Singleton instance is not granted.
Optimizations:
1. null assignment for $instance is not needed, all variables declared are null by default.
2. null === $check is faster than is_null($check).
3. Should use phpdoc for methods instead of inline comments, speaking of: missing type hint of $instance and return value of getInstance in phpdoc.
Hi FD,
I thought I’d number my points back so it made sense
Absolutely fair point. Completely forgot about __clone
I didn’t realise that it was any faster, but I know now for next time, thanks for that
I normally do phpdoc and type hint, I wrote this straight into the WYSIWYG so I didn’t code as I normally would (type hinting assumes I’m working/deploying somewhere with PHP7 of course)
In hindsight, I might write into my IDE first, then C&P it into the editor for the post, it’ll stop me making newb-looking errors because I wrote syntax into a text editor haha
Thanks!
Johno
Pingback:Layering Software Design on new or existing code bases