Skip to content

Implementação de singleton em PHP

Durante uma discussão hoje na lista php-especialistas, eu criei um protótipo para a implementação do padrão Singleton, mas que (na minha opinião) acabou ficando bem legal… Então, para não desperdiçar o trabalho e movimentar um pouco o blog, segue o código abaixo:


<?php
abstract class Singleton {
    static private $instance = array();

    final static public function instance($module) {
        if (!class_exists($module))
            throw new Exception("Module '{$module}' not found.");
        $module = strtolower($module);
        if (!isset(self::$instance[$module]))
            self::$instance[$module] = new $module;
        return self::$instance[$module];
    }
}
?>

Quer saber como ela funciona!? Essa classe abstrata, portanto não pode ser instanciada, funciona da seguitne forma: sempre que você quiser que uma determinada classe siga ao padrão Singleton, basta chama-la sempre através da classe acima, como segue:


<?php
require_once 'Singleton.php';

class ClassA {
    public $valueA = null;
}   

class ClassB {
    public $valueB = null;
} 

try {
    $objA1 = Singleton::instance('ClassA');
    $objA2 = Singleton::instance('ClassA');
    $objA1->valueA = 'ClassA instance 1';
    echo $objA2->valueA . "\n";

    $objB1 = Singleton::instance('ClassB');
    $objB2 = Singleton::instance('ClassB');
    $objB1->valueB = 'ClassB instance 1';
    echo $objB2->valueB . "\n";

    $objC1 = Singleton::instance('ClassC'); // exception!
} catch (Exception $ex) {
    echo "<b>Singleton Error:</b> {$ex->getMessage()}";
}
?>

E o resultado do código acima é:

ClassA instance 1
ClassB instance 1
Singleton Error: Module 'ClassC' not found.

E é isso ae, espero que esse código seja útil para mais alugém. :)

UPDATE1: Definido o método Singleton::instance como final, assim ele não poderá ser alterado por nenhuma classe que extenda a classe Singleton.

UPDATE2: Na versão 5.3 do PHP, foi introduzida uma funcionalidade chamada de Late static binding que faz com que possamos criar (sem nenhuma artimanha-extravagante) uma classe Singleton, onde todas as classes que a extenderem serão Singleton também. Algo parecido com o código abaixo.


<?php
require_once 'Singleton.php';

abstract class Singleton {
    static private $__CLASS__ = __CLASS__;
    static private $instance = null;

    final static public function instance() {
        if (static::$instance == null)
            static::$instance = new static::$__CLASS__;
        return static::$instance;
    }
}
?>

E nessa caso, a implementação fica algo mais ou menos parecido com:


<?php
class ClassA extends Singleton {
    // Singleton implementation
    static private $__CLASS__ = __CLASS__;
    static private $instance = null;

    prublic $value = null;
}

$objA1 = ClassA::instance();
$objA2 = ClassA::instance();
$objA1->value = 'ClassA instance 1';
echo $objA2->value . "\n";
?>

Nessa versão 5.3, ainda dará para usar os namespaces organizando um pouco melhor essa estrutura. :)

One Trackback/Pingback

  1. Arthur via Rec6 on 28-Aug-08 at 9:53 pm

    Implementação de Singleton pattern em PHP…

    Durante uma discussão na lista php-especialistas, criei um protótipo de implementação do Singleton e que (na minha opinião) acabou ficando bem legal%6 Então, para não desperdiçar o trabalho e movimentar um pouco meu blog, estou publicando o res…

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*