1.8. Singleton

THIS IS CONSIDERED TO BE AN ANTI-PATTERN! FOR BETTER TESTABILITY ANDMAINTAINABILITY USE DEPENDENCY INJECTION!

1.8.1. Purpose

To have only one instance of this object in the application that willhandle all calls.

1.8.2. Examples

  • DB Connector
  • Logger (may also be a Multiton if there are many log files forseveral purposes)
  • Lock file for the application (there is only one in the filesystem…)

1.8.3. UML Diagram

Alt Singleton UML Diagram

1.8.4. Code

You can also find this code on GitHub

Singleton.php

  1. <?php
  2.  
  3. namespace DesignPatterns\Creational\Singleton;
  4.  
  5. final class Singleton
  6. {
  7. /**
  8. * @var Singleton
  9. */
  10. private static $instance;
  11.  
  12. /**
  13. * gets the instance via lazy initialization (created on first usage)
  14. */
  15. public static function getInstance(): Singleton
  16. {
  17. if (null === static::$instance) {
  18. static::$instance = new static();
  19. }
  20.  
  21. return static::$instance;
  22. }
  23.  
  24. /**
  25. * is not allowed to call from outside to prevent from creating multiple instances,
  26. * to use the singleton, you have to obtain the instance from Singleton::getInstance() instead
  27. */
  28. private function __construct()
  29. {
  30. }
  31.  
  32. /**
  33. * prevent the instance from being cloned (which would create a second instance of it)
  34. */
  35. private function __clone()
  36. {
  37. }
  38.  
  39. /**
  40. * prevent from being unserialized (which would create a second instance of it)
  41. */
  42. private function __wakeup()
  43. {
  44. }
  45. }

1.8.5. Test

Tests/SingletonTest.php

  1. <?php
  2.  
  3. namespace DesignPatterns\Creational\Singleton\Tests;
  4.  
  5. use DesignPatterns\Creational\Singleton\Singleton;
  6. use PHPUnit\Framework\TestCase;
  7.  
  8. class SingletonTest extends TestCase
  9. {
  10. public function testUniqueness()
  11. {
  12. $firstCall = Singleton::getInstance();
  13. $secondCall = Singleton::getInstance();
  14.  
  15. $this->assertInstanceOf(Singleton::class, $firstCall);
  16. $this->assertSame($firstCall, $secondCall);
  17. }
  18. }