Menu
Coddy logo textTech

Patron Singleton

Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 71 sur 91.

Le pattern Singleton est un patron de conception de création qui garantit qu'une classe n'a qu'une seule instance tout au long du cycle de vie de votre application. Il fournit également un point d'accès global à cette instance.

Ce patron est utile lorsque vous avez besoin d'exactement un seul objet pour coordonner les actions à travers le système, tel qu'une connexion à une base de données, un gestionnaire de configuration ou un système de journalisation (logger). Créer plusieurs instances de ceux-ci gaspillerait des ressources ou causerait un comportement incohérent.

Voici comment implémenter un Singleton en PHP :

<?php
class Database {
    private static ?Database $instance = null;
    
    private function __construct() {
        // Le constructeur privé empêche l'instanciation directe
    }
    
    public static function getInstance(): Database {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    public function query(string $sql): string {
        return "Executing: $sql";
    }
}

$db1 = Database::getInstance();
$db2 = Database::getInstance();

echo $db1 === $db2 ? "Same instance" : "Different instances";

Sortie :

Same instance

Le patron repose sur trois éléments clés : un constructeur privé qui empêche d'utiliser new directement, une propriété statique qui détient l'instance unique, et une méthode statique qui crée l'instance lors du premier appel et la retourne lors des appels suivants.

Pour rendre le Singleton véritablement robuste, vous devriez également empêcher le clonage et la désérialisation :

<?php
private function __clone() {}
public function __wakeup() {
    throw new Exception("Cannot unserialize singleton");
}
challenge icon

Défi

Facile

Construisons un gestionnaire de configuration en utilisant le Singleton Pattern. Dans les applications réelles, vous souhaitez généralement une source de vérité unique pour les paramètres de configuration — avoir plusieurs objets de configuration pourrait entraîner un comportement incohérent dans votre système.

Vous organiserez votre code sur deux fichiers :

  • Config.php — Créez une classe Config qui implémente le Singleton Pattern. Votre gestionnaire de configuration doit :
    • Stocker les paramètres dans une propriété de type tableau privée
    • Avoir un constructeur privé qui initialise le tableau de paramètres comme vide
    • Fournir une méthode statique getInstance() qui retourne l'instance unique
    • Empêcher le clonage en rendant __clone() privé
    • Inclure une méthode set(string $key, string $value): void pour stocker un paramètre
    • Inclure une méthode get(string $key): ?string qui retourne la valeur pour une clé, ou null si la clé n'existe pas
    • Inclure une méthode getAll(): array qui retourne tous les paramètres
  • main.php — Incluez le fichier Config. Vous recevrez deux entrées : une clé et une valeur.

    Récupérez l'instance de Config et définissez un paramètre par défaut avec la clé "app_name" et la valeur "MyApp".

    Récupérez une deuxième référence à l'instance de Config (en utilisant à nouveau getInstance()) et utilisez-la pour définir un autre paramètre en utilisant la clé et la valeur provenant des entrées.

    Enfin, vérifiez que le Singleton fonctionne correctement :

    • Affichez "Same instance: true" ou "Same instance: false" selon que les deux références pointent vers le même objet (utilisez === pour comparer)
    • Affichez "Settings count: [count]" montrant le nombre total de paramètres stockés (utilisez count() sur le résultat de getAll())
    • Affichez "App name: [value]" montrant le paramètre app_name récupéré via la deuxième référence

Ce défi démontre l'avantage principal du Singleton Pattern : peu importe le nombre de fois que vous appelez getInstance(), vous obtenez toujours le même objet, garantissant que toutes les parties de votre application partagent le même état de configuration.

Aide-mémoire

Le Singleton Pattern (ou patron de conception Singleton) garantit qu'une classe n'a qu'une seule instance tout au long du cycle de vie de votre application et fournit un point d'accès global à cette instance.

Ce patron est utile pour des objets tels que les connexions aux bases de données, les gestionnaires de configuration ou les journaux (loggers), où plusieurs instances gaspilleraient des ressources ou causeraient un comportement incohérent.

Implémentation de base du Singleton :

<?php
class Database {
    private static ?Database $instance = null;
    
    private function __construct() {
        // Le constructeur privé empêche l'instanciation directe
    }
    
    public static function getInstance(): Database {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$db1 = Database::getInstance();
$db2 = Database::getInstance();

echo $db1 === $db2 ? "Same instance" : "Different instances";
// Résultat : Same instance

Éléments clés :

  • Constructeur privé — empêche l'utilisation directe de new
  • Propriété statique — contient l'instance unique
  • Méthode statique — crée l'instance lors du premier appel et la retourne lors des appels suivants

Empêcher le clonage et la désérialisation :

<?php
private function __clone() {}

public function __wakeup() {
    throw new Exception("Cannot unserialize singleton");
}

Essayez vous-même

<?php

require_once 'Config.php';

// Lire l'entrée
$key = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: Obtenir l'instance de Config et définir "app_name" sur "MyApp"

// TODO: Obtenir une deuxième référence à Config en utilisant à nouveau getInstance()

// TODO: Utiliser la deuxième référence pour définir le paramètre en utilisant $key et $value de l'entrée

// TODO: Vérifier que le Singleton fonctionne :
// - Afficher "Same instance: true" ou "Same instance: false" basé sur la comparaison ===
// - Afficher "Settings count: [count]" montrant le nombre total de paramètres
// - Afficher "App name: [value]" montrant app_name récupéré via la deuxième référence

?>
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet