Skip to content
This repository has been archived by the owner on Jan 16, 2019. It is now read-only.

Singleton scope

Frank Kleine edited this page Aug 3, 2014 · 2 revisions

The singleton scope

Multiple calls to $injector->getInstance('Car'); will return different objects. In most cases, this is probably what you want, as the IoC framework behaves like the new operator. If you want to create only one instance of the BMW class, you can easily convert the BMW class to a singleton.

$binder = new stubbles\ioc\Binder();
$binder->bind('Car')->to('BMW')->asSingleton();
// other bindings

$injector = $binder->getInjector();
$bmw1 = $injector->getInstance('Car');
$bmw2 = $injector->getInstance('Car');

if ($bmw1 === $bmw2) {
    echo "Same object.\n";
}

Using asSingleton() makes sure that the instance is created only once and subsequent calls to getInstance() will return the same instance.

Another way to treat a class as a singleton is using the @Singleton annotation, which is used to annotate the class. The following example makes sure, that the application uses only one instance of the class Schst:

/**
 * @Singleton
 */
class Schst implements Person {
    public function sayHello() {
        echo "My name is Stephan\n";
    }
}

The following code will now create two instances of the class BMW, but both should have a reference to the same Schst instance:

$binder = new stubbles\ioc\Binder();
$binder->bind('Car')->to('BMW');
// other bindings

$injector = $binder->getInjector();
$bmw1 = $injector->getInstance('Car');
$bmw2 = $injector->getInstance('Car');

var_dump($bmw1);
var_dump($bmw1);

If you run the code snippet, you get the following output:

object(BMW)#34 (3) {
  ["driver:protected"]=>
  object(Schst)#50 (0) {
  }
  ["engine:protected"]=>
  object(TwoLitresEngine)#38 (0) {
  }
  ["tire:protected"]=>
  object(Goodyear)#41 (0) {
  }
}
object(BMW)#30 (3) {
  ["driver:protected"]=>
  object(Schst)#50 (0) {
  }
  ["engine:protected"]=>
  object(TwoLitresEngine)#44 (0) {
  }
  ["tire:protected"]=>
  object(Goodyear)#39 (0) {
  }
}

As you can see, the two BMW instances have different object handles (#30 and #34), but the $driver properties point to the same Schst instance (object handle #50).

Implementing the singleton pattern never has been this easy.

Clone this wiki locally