DEV Community

Bruno Barros
Bruno Barros

Posted on

Padrão Singleton com PHP

O padrão singleton tem como finalidade centralizar a criação de um objeto, mantendo o vivo durante todo o ciclo de execução.

SINGLETON, O ANTI-PATTERN
Para muitos, o padrão Singleton é considerado um anti-
pattern por conta do seu uso em forma estática (chamando a
classe sem precisar instanciá-la) e, principalmente, pelo
acesso global à instância da classe. Os problemas de utilizar
classes estáticas são vários: não podemos trabalhar com
interfaces, nosso código fica com um acoplamento mais alto,
entre outros.
(quote do livro: Design pattern com PHP 7 - página 43.)

Dito isso, o singleton ainda é muito utilizado no mercado quando precisamos de uma instância unica.

Com esse controle, impedimos a criação descontralada de instancias de classes. Este padrão é muito utilizado quando estamos lidando com classes/frameworks de logs.

<?php 

namespace Singleton; 

class LogsSingleton 
{

    /** @var self $singleton instância da classe de logs. */
    protected static LogsSingleton $instancia;

    /** os métodos construtor, clone e wake up precisam ser privados, para que a classe só seja criado via método getInstancia */
    private function __construct()
    {

    }
    private function __clone()
    {

    }
    private function __wakeup()
    {

    }

    public static function getInstancia() : self 
    { 
        // self => se refere a própria classe 
        // Se a instancia estiver vazia, nenhuma classe foi criada ainda 
        if (empty(self::$instancia))
        {
            self::$instancia = new self();
        }
        return self::$instancia;
    }

    /** function para gravar dados em um arquivo de texto, simulando log */
    public function gravarLog(array $dados):void 
    {
        $nomeArquivo = 'logs.txt';

        $logsAnteriores = [];

        if (filesize($nomeArquivo) > 0)
        {
            $conteudoArquivo = file_get_contents($nomeArquivo);
            // com esse array vazio, impedimos erros casos o arquivo inicial esteja vazio
            $logsAnteriores = json_decode($conteudoArquivo, true);
        }
        $logsAnteriores[] = $dados;
        // escreve no arquivo 
        $arquivo = fopen($nomeArquivo, 'w');
        fwrite($arquivo, json_encode($logsAnteriores));
        fclose($arquivo);
    }
}

$instanciaLogs = LogsSingleton::getInstancia();
print_r($instanciaLogs);
Enter fullscreen mode Exit fullscreen mode

Criamos a propriedade $instancia de forma estática, já que ela será responsável por garantir o acesso único a instância da classe. Os métodos mágicas __construct, __wakeup e __clone estão privados para impedir que sejam chamados e criem instâncias da classe.

Se tentarmos criar uma instância desta classe, sem utilizar o método getInstancia(), teremos um fatal error.

Testando:


$instancia = LogsSingleton::getInstancia();
$instanciaNova = LogsSingleton::getInstancia(); 

if ($instancia === $instanciaNova) 
{ 
 echo "são iguais";
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)