PDO (PHP Data Objects) é uma extensão do PHP que fornece uma camada de abstração para acesso a bancos de dados. Com ela, você pode interagir com diferentes SGBDs (MySQL, PostgreSQL, SQLite, etc.) usando a mesma interface, o que facilita a portabilidade do código. Além disso, PDO oferece recursos avançados como prepared statements, que ajudam a prevenir injeção de SQL, e tratamento de erros via exceções.

Nesta introdução, vamos explorar os conceitos fundamentais para começar a usar PDO em seus projetos PHP.

Por que PDO

Antes do PDO, os desenvolvedores PHP usavam extensões específicas para cada banco de dados, como mysqli para MySQL ou pg_* para PostgreSQL. Isso tornava o código fortemente acoplado a um SGBD específico; se fosse necessário mudar de banco, grande parte do código precisaria ser reescrita.

PDO resolve esse problema oferecendo uma API uniforme. Com ele, você pode trocar o banco de dados subjacente alterando apenas a string de conexão (DSN) e, em alguns casos, pequenos ajustes nas consultas SQL. Além disso, PDO suporta prepared statements com vinculação de parâmetros, o que é a maneira mais segura de executar consultas com dados fornecidos pelo usuário, prevenindo ataques de injeção de SQL.

Outros benefícios incluem:

  • Suporte a transações
  • Modos de fetch flexíveis (array associativo, objeto, etc.)
  • Tratamento de erros configurável (silencioso, warnings ou exceções)
  • Suporte a diversos drivers (MySQL, PostgreSQL, SQLite, Oracle, etc.)

Conectando

Para se conectar a um banco de dados usando PDO, você precisa criar uma instância da classe PDO. O construtor da classe recebe três parâmetros principais: o DSN (string de conexão), o nome de usuário e a senha. Opcionalmente, você pode passar um quarto parâmetro com opções de configuração.

Exemplo básico de conexão com MySQL:

$dsn = 'mysql:host=localhost;dbname=meu_banco;charset=utf8mb4';
$usuario = 'root';
$senha = '';

$pdo = new PDO($dsn, $usuario, $senha);

Se a conexão falhar, o PDO lançará uma exceção PDOException (se o modo de erro estiver configurado para exceções). Por isso, é comum envolver a criação da conexão em um bloco try-catch.

try {
    $pdo = new PDO($dsn, $usuario, $senha);
    echo "Conectado com sucesso!";
} catch (PDOException $e) {
    echo "Falha na conexão: " . $e->getMessage();
}

Depois de conectado, você pode executar consultas SQL usando métodos como query() para consultas simples ou prepare() e execute() para consultas parametrizadas.

DSN

DSN significa Data Source Name e é uma string que contém as informações necessárias para conectar ao banco de dados. A estrutura do DSN varia de acordo com o driver do banco. Geralmente, ele começa com o nome do driver (ex.: mysql, pgsql, sqlite), seguido por dois pontos e então os parâmetros específicos do driver.

Exemplos de DSN para diferentes bancos:

  • MySQL: mysql:host=localhost;port=3306;dbname=meu_banco;charset=utf8mb4
  • PostgreSQL: pgsql:host=localhost;port=5432;dbname=meu_banco;user=postgres;password=123
  • SQLite: sqlite:/caminho/para/arquivo.db
  • SQL Server: sqlsrv:Server=localhost;Database=meu_banco

Os parâmetros comuns incluem host (endereço do servidor), port (porta), dbname (nome do banco), charset (codificação de caracteres). Para SQLite, o DSN é simplesmente o caminho para o arquivo do banco.

É importante definir corretamente o charset para evitar problemas com caracteres especiais. No MySQL, por exemplo, recomenda-se usar utf8mb4 para suporte completo a Unicode.

Tratamento de erros (exceções)

Por padrão, o PDO não lança exceções quando ocorre um erro; ele apenas define um código de erro que pode ser verificado com errorCode() e errorInfo(). No entanto, é uma boa prática configurar o PDO para lançar exceções usando o método setAttribute:

$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Com essa configuração, qualquer erro de SQL (como uma consulta mal formada ou uma violação de chave) lançará uma exceção PDOException. Isso permite que você use blocos try-catch para capturar e tratar erros de forma elegante.

Exemplo completo com tratamento de exceções:

try {
    $pdo = new PDO($dsn, $usuario, $senha);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query("SELECT * FROM usuarios");
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        echo $row['nome'] . "
"; } } catch (PDOException $e) { echo "Erro: " . $e->getMessage(); }

Além do modo exceção, o PDO oferece outros modos de erro:

  • PDO::ERRMODE_SILENT (padrão): apenas define códigos de erro.
  • PDO::ERRMODE_WARNING: emite um aviso E_WARNING.

Para a maioria das aplicações, o modo exceção é o mais recomendado, pois força o tratamento adequado dos erros e evita que o script continue executando com estado inconsistente.

Boas práticas

Ao trabalhar com PDO, siga estas recomendações:

  • Sempre configure o modo de erro para exceções (ERRMODE_EXCEPTION).
  • Use prepared statements com parâmetros vinculados para consultas que envolvam dados do usuário.
  • Feche a conexão quando não for mais necessária (atribuindo null à variável PDO).
  • Não exponha detalhes da conexão em mensagens de erro em produção; capture a exceção e exiba uma mensagem genérica.
  • Use transações para operações que exigem atomicidade.

Referências

Exercícios

  1. Crie uma conexão PDO com MySQL usando o banco de dados teste, usuário root e senha vazia. Configure o modo de erro para exceções.

    ✓ Resposta:
    $dsn = 'mysql:host=localhost;dbname=teste;charset=utf8mb4';
    $usuario = 'root';
    $senha = '';
    
    try {
        $pdo = new PDO($dsn, $usuario, $senha);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        echo "Conectado!";
    } catch (PDOException $e) {
        echo "Erro: " . $e->getMessage();
    }
    
  2. Escreva um DSN para conectar a um banco PostgreSQL chamado meudb no servidor 192.168.1.100 na porta 5432.

    ✓ Resposta:
    'pgsql:host=192.168.1.100;port=5432;dbname=meudb'
    
  3. Qual é a diferença entre os modos de erro ERRMODE_SILENT e ERRMODE_EXCEPTION? Explique quando usar cada um.

    ✓ Resposta:No modo ERRMODE_SILENT, o PDO não gera nenhum aviso ou exceção; você deve verificar manualmente os erros com errorCode() e errorInfo(). Já no modo ERRMODE_EXCEPTION, qualquer erro lança uma exceção PDOException. Recomenda-se usar ERRMODE_EXCEPTION na maioria dos casos, pois obriga o tratamento de erros e simplifica o fluxo. O modo silencioso pode ser útil em scripts muito simples ou quando você deseja controlar totalmente a lógica de erro sem usar exceções.
  4. Conecte-se a um banco SQLite em memória e crie uma tabela test com uma coluna id inteira. Use exceções para tratar erros.

    ✓ Resposta:
    try {
        $pdo = new PDO('sqlite::memory:');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $pdo->exec("CREATE TABLE test (id INTEGER)");
        echo "Tabela criada.";
    } catch (PDOException $e) {
        echo "Erro: " . $e->getMessage();
    }
    
  5. Explique por que usar PDO é melhor do que usar funções específicas como mysqli_* para conectar a um banco MySQL. Dê pelo menos três razões.

    ✓ Resposta:1. Portabilidade: PDO permite trocar de banco de dados (MySQL para PostgreSQL) alterando apenas o DSN, sem reescrever o código. 2. Segurança: PDO suporta prepared statements com parâmetros vinculados, prevenindo injeção de SQL de forma mais limpa que as funções antigas. 3. Orientação a objetos: PDO é orientado a objetos, facilitando a integração com frameworks modernos. 4. Tratamento de erros: Oferece modos de erro flexíveis, incluindo exceções. 5. Recursos adicionais: Suporte a transações, múltiplos modos de fetch, etc.