Classe para conexão com banco de dados em PDO

Olá pessoal, este é o nosso primeiro post oficial.

Como nosso blog falará principalmente sobre desenvolvimento Web, nada melhor do que começar com um post ensinado como fazer uma classe em PHP para conexão a banco de dados MySQL usando PDO (PHP Data Object).

O PDO fornece uma camada de abstração de acesso a dados, o que significa que, independentemente de qual banco de dados você está usando, você pode usar as mesmas funções para realizar consultas e buscar dados. Mas atenção, o PDO não fornece uma abstração de banco de dados, ele também não reescreve ou emula comandos SQL que podem não estar presentes em um determinado tipo de banco de dados.

Na prática, usar o PDO como método de conexão e acesso aos dados do banco, significa que se um dia você precisar mudar o banco de dados do seu sistema de MySQL para PostgreSQL, por exemplo, você não precisará alterar todas as funções de consultas mysql_query() para pg_query() no seu código fonte PHP. Está é uma das principais vantagens de usar PDO.

Vamos ao código da nossa classe de conexão.

/**
 * Classe Singleton para Conexao ao banco de dados
 *
 * @author Marcos de P. Muniz
 * @version 1.0
 */
class Conexao 
{

    /**
     * Instancia de conexao PDO
     * @var PDO
     */
    private static $instance = null;
    /**
     * Tipo do banco de dados
     * 
     * Pode ser:
     * <li>MySQL</li>
     * <li>PostgreSQL</li>
     * <li>SQL Server</li>
     * <li>Oracle</li>
     * <li>SQLite</li>
     * @var string
     */
    private static $dbType = "mysql";
    /**
     * Host do banco de dados
     * @var string
     */
    private static $host = "localhost";
    /**
     * Usuario de conexao ao banco de dados
     * @var string
     */
    private static $user = "usuario_de_conexao_ao_banco";
    /**
     * Senha de conexao ao banco de dados
     * @var string
     */
    private static $senha = "senha_de_conexao_ao_banco";
    /**
     * Nome do banco de dados
     * @var string
     */
    private static $db = "nome_do_banco";
    /**
     * Se a conexao deve ser persistente
     * @var boolean
     */
    protected static $persistent = false;
    /**
     * Lista de tabelas do banco de dados
     * 
     * Esta lista serve para padronizar a utilizacao das tabelas nas consultas
     * para caso seja necessario alterar o nome de alguma tabela o impacto na
     * programacao seja o minimo possivel.
     * @var array
     */
    private static $tabelas = array(
            'TB_USUARIOS' => 'usuarios',
            'TB_PARAMETROS' => 'parametros',
            'TB_MODULOS' => 'modulos'
        );   
    
    /**
     * Retorna a instancia de conexao ao banco de dados
     * 
     * Caso a instancia de conexao ja exista, apenas a retorna, caso ainda
     * nao exista, cria a instancia e a retorna.
     * 
     * @return PDO
     */
    public static function getInstance() 
    {

        if(self::$persistent != FALSE)
            self::$persistent = TRUE;
        
        if(!isset(self::$instance)){
            try {            
                
                self::$instance = new \PDO(self::$dbType . ':host=' . self::$host . ';dbname=' . self::$db
                        , self::$user
                        , self::$senha
                        , array(\PDO::ATTR_PERSISTENT => self::$persistent));
                
            } catch (\PDOException $ex) {
                exit ("Erro ao conectar com o banco de dados: " . $ex->getMessage());
            }
        }
        
        return self::$instance;
        
    }

    /**
     * Fecha a instancia de conexao ao banco de dados
     */
    public static function close() 
    {
        if (self::$instance != null)
            self::$instance = null;
    }
    
    /**
     * Retorna a tabela correspondente a chave informada. 
     * 
     * @param string $chave Nome da chave do array $tabelas que armazena a tabela a ser retornada
     * @return string
     */
    public static function getTabela($chave)
    {
        return self::$tabelas[$chave];
    }

}

Os comentários da classe são auto explicativos.
Para utiliza-la primeiro será necessário alterar os parâmetros $dbType, $host, $user, $senha e $db para os valores correspondentes para conexão a sua base de dados. Também será necessário alterar os valores do array $tabelas informando o nome das tabelas do seu banco de dados seguindo o padrão do exemplo da classe.

Supondo que você salvou a classe como Conexao.php, veja abaixo como ficaria a utilização de nossa classe.

// inclui a classe de conexão
require_once ('Conexao.php');

// atribui a instância de conexão na variável
$db = Conexao::getInstance();

// consulta que retorna a lista de usuários do banco ordenado por nome
$query = $db->query("SELECT * FROM " . Conexao::getTabela('TB_USUARIOS') . " ORDER BY nome");

// escreve cada usuário encontrado na consulta
foreach($query->fetchAll(PDO::FETCH_ASSOC) as $usuario) {
    echo $usuario['nome'] . '<br>';
}

Como você pode ter percebido, não foi necessário instanciar nossa classe de conexão para usa-la, pois nossa classe foi toda planejada para trabalhar com métodos static por ela ser uma classe Singleton.

Em nosso próximo post iremos explicar o que é uma classe Singleton.

Marcos de P. Muniz

Graduado em Sistemas de Informação pela UEMG, é Pós Graduado em Segurança da Informação pela Faculdade Pitágoras, é desenvolvedor PHP desde 2006, trabalha como Analista / Desenvolvedor em uma empresa que atua na área de ensino a distância, faz freelancer criando sites, sistemas e portais utilizando PHP, MySQL e jQuery.

Você pode gostar...

9 Resultados

  1. Rodrigo disse:

    Olá, parabéns pelo post!
    Sei que o post é um pouco antigo, mais ai vai uma pergunta. Percebi que você não fechou a conexão, mais tem o método “close”, qual é a melhor maneira de utiliza-lo? Depois de executar a consulta?

    Abs!

    • Olá Rodrigo, obrigado pelo comentário.

      Eu recomendo fechar a conexão no ponto em seu código em que você não precisará mais de uma conexão com seu banco de dados.
      Se você fechar a conexão logo depois de retornar os dados da sua consulta com o comando fetch e 50 linhas depois disso, no mesmo código, você precisar fazer outra consulta, então seria necessário estabelecer a conexão novamente no banco de dados, essa prática faria seu código ficar um pouco mais lento para executar.

  2. Eduardo Wilson disse:

    Ola, eu adorei esta classe ela pode vir a me ajudar cm o problema de lentidao de resultados.
    Estou fazendo uma consulta em outro servidor, porem o tempo de resposta esta muito alto, porém tentando utilizar seu codigo ele me retorna o erro
    PHP Fatal error: Can’t use method return value in write context
    E nao consigo solucionar, meu conhecimento em PHP ainda e básico

    • Olá Eduardo, obrigado pelo comentário.

      O erro informado acontece porque exemplo de utilização da classe estava errado. Já fiz a correção aí no código e testei, agora está funcionando normalmente. No seu código, localize a linha correspondente a linha 11 do meu código de exemplo de utilização da classe. Basta substituir esta linha no seu código deixando como está atualmente no meu exemplo que tudo funcionará corretamente.

      Sobre sua consulta está demorando a responder, o problema deve ser no servidor do banco de dados e não no método usado para conexão, verifique com o pessoal que hospeda esse servidor.

      • Eduardo Wilson disse:

        Ola marcos, Obrigado pela ajuda, realmente funcionou.
        E sei que estou fugindo um pouco do tópico mas o problema não é no banco de dados eu acho.
        A empresa possui mais de 1 site que realizam buscar neste mesmo servidor, porém este outro site feito em ASP tem a busca rápida.
        ja procurei de tudo e nao sei como resolver.
        mas obrigado mesmo assim.
        Ajudou muito

  3. Erwann Pierre Caille disse:

    só isso para falar é genial ! Obrigado…

  4. Eu sou humano!

    Marcos muito bacana isso que publicou, parabéns, comecei a dar uma olhada em PDO hoje, desde que comecei com PHP na empresa usei o framework PHP e fiquei sem vergonha, rsss, sem entrar muito a fundo no PHP. Lembro que na faculdade fizemos um Singleton em java e definimos um máximo de conexões simultâneas, como faria isso aqui.

  5. Marcelo disse:

    Marcos, bom dia!
    Caso você fosse utilizar o controle de transação nesse exemplo como você faria?
    Parabéns pelo post!

    • Ola Marcelo, desculpe a demora para responder.
      Vamos lá, é simples, basta você iniciar a transação com $db->beginTransaction(); antes de fazer suas querys.
      O Ideal é quando você for usar transação você fazer isso dentro de uma estrutura try-catch, porque aí você pode chamar um $db->rollBack(); quando necessário lançando uma Exception para forçar o rollback. O commit ficaria $db->commit();

Deixe uma resposta

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