Conexão Única com PDO usando o Padrão Singleton em PHP

Conexão Única com PDO usando o Padrão Singleton em PHP

Gerenciar múltiplas conexões com o banco de dados em uma mesma requisição pode esgotar os recursos do servidor e desacelerar a aplicação. A aplicação do padrão de projeto Singleton na classe de conexão PDO garante uma instância única e reutilizável, combinada com Prepared Statements para neutralizar vulnerabilidades de SQL Injection.

PHP

<?php

/**
 * Gerenciador de conexão com banco de dados utilizando o padrão Singleton.
 */
class Database
{
    private static ?PDO $instance = null;

    // Construtor privado impede a criação direta de objetos via 'new'
    private function __construct() {}

    // Impede a clonagem da instância Singleton
    private function __clone() {}

    /**
     * Retorna a instância única da conexão PDO.
     */
    public static function getInstance(): PDO
    {
        if (self::$instance === null) {
            $dsn = 'mysql:host=127.0.0.1;dbname=empresa_db;charset=utf8mb4';
            
            self::$instance = new PDO($dsn, 'db_user', 'senha_segura_456', [
                PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                PDO::ATTR_EMULATE_PREPARES   => false,
            ]);
        }

        return self::$instance;
    }

    /**
     * Executa uma consulta SELECT parametrizada contra SQL Injection.
     */
    public static function query(string $sql, array $params = []): array
    {
        $stmt = self::getInstance()->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll();
    }
}

// --- Exemplo de Uso Prático ---

try {
    // Consulta protegida com parâmetros posicionais ou nomeados
    $sql = "SELECT id, nome, email FROM clientes WHERE cidade = :cidade AND ativo = :status";
    $parametros = [
        ':cidade' => 'São Paulo',
        ':status' => 1
    ];

    // Execução sem instanciar explicitamente o banco várias vezes
    $clientes = Database::query($sql, $parametros);

    echo "Registros encontrados: " . count($clientes) . PHP_EOL;
    print_r($clientes);

} catch (PDOException $e) {
    error_log("Falha ao consultar banco: " . $e->getMessage());
    echo "Erro interno no processamento da solicitação." . PHP_EOL;
}
  • Encapsulamento Restritivo (private __construct e __clone): Bloqueia a instanciação externa da classe via operador new ou por clonagem, forçando o uso exclusivo do método estático getInstance().
  • Reaproveitamento de Conexão: Reduz a sobrecarga de E/S no servidor MySQL abrindo o socket de rede uma única vez por ciclo de vida da requisição HTTP.
  • Proteção contra SQL Injection: O método Database::query() utiliza o $pdo->prepare() para assegurar o isolamento estrito entre a sintaxe do comando SQL e os argumentos enviados.
  • Desativação de Prepared Statements Emulados: A instrução PDO::ATTR_EMULATE_PREPARES => false garante que a preparação da consulta ocorra diretamente na engine do banco de dados, maximizando a segurança.

Thales de Oliveira Gomes

Thales de Oliveira Gomes é gestor de Tecnologia da Informação, especialista em infraestrutura de redes, computação em nuvem e operações de TI hospitalar, com mais de 18 anos de experiência na área. Graduado em Gestão de TI e pós-graduado em Engenharia de Redes e Telecomunicações, Cloud Computing, Redes de Computadores e Gestão Hospitalar, construiu uma trajetória sólida liderando projetos de alta complexidade, como a implementação e migração para nuvem de sistemas ERP de grande porte. Sua atuação no setor o levou a ser indicado ao prêmio IT Leaders Brasil na categoria Rising Leaders. Além da carreira corporativa e da paixão por tecnologia, Thales é autor independente com mais de 70 obras publicadas sobre redes, segurança da informação, Linux e física, além de criador de conteúdo no blog Vetor Tech e na plataforma CiberDicas. No universo das artes e do entretenimento, atua como produtor de música eletrônica sob o projeto Yknex, cria ilustrações digitais e compartilha walkthroughs de games no YouTube.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *