DEV Community

Cover image for PHP Design Patterns: Singleton
Antonio Silva
Antonio Silva

Posted on

PHP Design Patterns: Singleton

What is Singleton?

Singleton is a creational design pattern, which ensures that only one object of this type exists and provides a single point of access to it for any other code.

Singleton

Just like a global variable, the Singleton pattern allows you to access an object from anywhere in the program. However, it also protects that instance from being overwritten by other code.

Example

Step 1 - Directory System:

πŸ“¦ Singleton
 ┣ πŸ“œ Preferences.php
 ┣ πŸ“œ Application.ini
 β”— πŸ“œ index.php
Enter fullscreen mode Exit fullscreen mode

Step 2 - Preferences Class:

<?php

namespace Singleton;

class Preferences
{
    private array $data;
    private static object $instance;
}

Enter fullscreen mode Exit fullscreen mode
  • construct method
// Constructor method is private so we can have a global object.
private function __construct()
{
    // The data property receives information from the application file.
    $this->data = parse_ini_file('application.ini');
}
Enter fullscreen mode Exit fullscreen mode
  • getInstance method
// Method for creating an instance or rescuing an already instantiated object.
public static function getInstance(): object
{
    // if there is no instance.
    if (empty(self::$instance)) {
        // Create a new instance.
        self::$instance = new self();
    }

    // return instance.
    return self::$instance;
}

Enter fullscreen mode Exit fullscreen mode
  • setData and getData methods
// Method for getting information.
public function getData(string $key): mixed
{
    return $this->data[$key];
}

// Method for inserting or changing information.
public function setData(string $key, mixed $value): void
{
    $this->data[$key] = $value;
}
Enter fullscreen mode Exit fullscreen mode
  • save method
// Method for writing information to the file application.ini
public function save(): void
{
    // Variable for information.
    $string = '';
    // If there is any information on date.
    if ($this->data) {
        // Traverses the data vector.
        foreach ($this->data as $key => $value) {
            // Fills the string variable with the information.
            $string .= "{$key} = \"{$value}\" \n";
        }
    }

    // Write information to the file.
    file_put_contents('application.ini', $string);
}

Enter fullscreen mode Exit fullscreen mode

Testing

<?php

require_once 'Preferences.php';

use Singleton\Preferences;

$p1 = Preferences::getInstance();
var_dump($p1);

$p2 = Preferences::getInstance();
var_dump($p2);

Enter fullscreen mode Exit fullscreen mode
object(Singleton\Preferences)[1]
  private array 'data' => 
    array (size=0)
      empty

object(Singleton\Preferences)[1]
  private array 'data' => 
    array (size=0)
      empty
Enter fullscreen mode Exit fullscreen mode

Insert Data

<?php

require_once 'Preferences.php';

use Singleton\Preferences;

$p1 = Preferences::getInstance();
$p1->setData('Language', 'en');
$p1->save();

$p2 = Preferences::getInstance();
print $p2->getData('Language');
var_dump($p2);
Enter fullscreen mode Exit fullscreen mode
Language: en

object(Singleton\Preferences)[1]
  private array 'data' => 
    array (size=1)
      'Language' => string 'en' (length=2)
Enter fullscreen mode Exit fullscreen mode

Objects p1 and p2 have the same instance.

Top comments (1)

Collapse
 
websilvercraft profile image
websilvercraft

Singleton pattern makes the code less flexible, because you can not extend the singleton class, so it breaks 2 of the solid design principles: open close principle and and single responsibility principle. I find the alternative implementations of singleton pattern in php, using functions, more flexible.