Go with a class property. There are a few advantages...
class Foo {
protected static $instance = null;
public static function instance() {
if (is_null(self::$instance)) {
self::$instance = new Foo();
}
return self::$instance;
}
}
First, it's easier to perform automated tests. You can create a mock foo class to "replace" the instance so that other classes which depend on foo will get a copy of the mock instead of the original:
class MockFoo extends Foo {
public static function initialize() {
self::$instance = new MockFoo();
}
public static function deinitialize() {
self::$instance = null;
}
}
Then, in your test cases (assuming phpunit):
protected function setUp() {
MockFoo::initialize();
}
protected function tearDown() {
MockFoo::deinitialize();
}
This gets around a common gripe with singletons that they are hard to test.
Second, it makes your code more flexible. If you ever want to "replace" the functionality at run time in that class, all you need to do is subclass it and replace self::$instance
.
Third, it allows you to operate on the instance in other static function. This isn't a huge deal for single instance classes (a true singleton) since you can just call self::instance()
. But if you have multiple "named" copies (say for database connections or other resources where you want more than one, but don't want to create a new one if they already exist), it becomes dirty because you then need to keep track of the names:
protected static $instances = array();
public static function instance($name) {
if (!isset(self::$instances[$name])) {
self::$instances[$name] = new Foo($name);
}
return self::$instances[$name];
}
public static function operateOnInstances() {
foreach (self::$instances as $name => $instance) {
//Do Something Here
}
}
One other note, I wouldn't make the constructor private. It will make it impossible to extend or test properly. Instead, make it protected so that you can sub-class if needed and still operate on the parent...