PDO: introdução
Esta aula introduz o PDO (PHP Data Objects), uma extensão para acesso a banco de dados de forma segura e portável. Você aprenderá por que usar PDO, como conectar via DSN, e como configurar o tratamento de erros com exceções.
O PDO (PHP Data Objects) é uma extensão do PHP que define uma interface leve e consistente para acesso a bancos de dados. Diferente das extensões específicas como mysqli ou pg_*, o PDO oferece uma camada de abstração que permite trocar de SGBD (MySQL, PostgreSQL, SQLite, etc.) com mínimas alterações no código. Além disso, ele suporta prepared statements, que são essenciais para prevenir ataques de injeção SQL.
Nesta aula, vamos explorar os conceitos fundamentais do PDO: por que ele é a escolha recomendada para projetos modernos, como estabelecer uma conexão usando DSN, e como configurar o modo de tratamento de erros para trabalhar com exceções. Ao final, você terá uma base sólida para começar a usar PDO em seus projetos.
Por que PDO
Antes do PDO, os desenvolvedores PHP usavam extensões específicas para cada banco de dados, como mysql_* (obsoleta) ou mysqli para MySQL, e pg_* para PostgreSQL. Cada uma tinha sua própria API, o que dificultava a portabilidade do código. Se um projeto precisasse migrar de MySQL para PostgreSQL, era necessário reescrever grande parte das consultas e funções de conexão.
O PDO resolve isso fornecendo uma interface única para múltiplos bancos de dados. Você usa as mesmas funções para conectar, executar consultas e tratar erros, independentemente do SGBD. Além disso, o PDO incentiva o uso de prepared statements, que separam os dados do comando SQL, eliminando riscos de injeção SQL. Outra vantagem é o suporte a transações, que permite agrupar operações em blocos atômicos.
Em resumo, PDO é a extensão recomendada pela comunidade PHP para acesso a banco de dados em aplicações modernas, por sua segurança, portabilidade e facilidade de uso.
Conectando
Para se conectar a um banco de dados usando PDO, você cria uma instância da classe PDO. O construtor recebe três parâmetros principais: o DSN (string de conexão), o nome de usuário e a senha. Opcionalmente, pode-se passar um array de opções adicionais.
Exemplo de conexão com MySQL:
<?php
$dsn = 'mysql:host=localhost;dbname=teste;charset=utf8mb4';
$usuario = 'root';
$senha = '';
try {
$pdo = new PDO($dsn, $usuario, $senha);
echo "Conectado com sucesso!";
} catch (PDOException $e) {
echo "Erro ao conectar: " . $e->getMessage();
}
?>
No exemplo acima, usamos um bloco try/catch para capturar exceções. Por padrão, o PDO não lança exceções; ele define o modo de erro como silencioso. Para que exceções sejam lançadas, é necessário configurar o atributo PDO::ATTR_ERRMODE para PDO::ERRMODE_EXCEPTION, como veremos na seção de tratamento de erros.
DSN
DSN significa Data Source Name e é uma string que contém as informações necessárias para conectar ao banco de dados. A sintaxe básica é:
tipo_banco:opção=valor;opção=valor
O prefixo tipo_banco indica o driver do banco (ex.: mysql, pgsql, sqlite, sqlsrv). As opções variam conforme o driver. Exemplos comuns:
- MySQL:
mysql:host=localhost;port=3306;dbname=banco;charset=utf8mb4 - PostgreSQL:
pgsql:host=localhost;port=5432;dbname=banco;user=usuario;password=senha(usuário e senha também podem ser passados separadamente) - SQLite:
sqlite:/caminho/para/arquivo.db
É importante especificar o charset (como utf8mb4 no MySQL) para evitar problemas com caracteres especiais. O DSN pode incluir outras opções como unix_socket para conexões via socket Unix.
Tratamento de erros (exceções)
Por padrão, o PDO não lança exceções quando ocorre um erro; ele apenas define códigos de erro que podem ser verificados com errorCode() e errorInfo(). Para um tratamento mais robusto, é recomendável configurar o PDO para lançar exceções do tipo PDOException.
Isso é feito através do método setAttribute() ou passando opções no construtor. Exemplo:
<?php
$dsn = 'mysql:host=localhost;dbname=teste;charset=utf8mb4';
$opcoes = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
$pdo = new PDO($dsn, 'root', '', $opcoes);
?>
Agora, qualquer erro de consulta ou conexão lançará uma exceção que pode ser capturada com try/catch. Isso simplifica o tratamento de erros, pois você pode concentrar a lógica de erro em um único bloco, em vez de verificar códigos de erro após cada operação.
Exemplo de consulta com tratamento de exceção:
<?php
try {
$stmt = $pdo->query('SELECT * FROM usuarios');
while ($row = $stmt->fetch()) {
echo $row['nome'] . "<br>";
}
} catch (PDOException $e) {
echo "Erro na consulta: " . $e->getMessage();
}
?>
Além do modo de exceção, existem outros modos de erro: PDO::ERRMODE_SILENT (padrão) e PDO::ERRMODE_WARNING. Recomenda-se usar ERRMODE_EXCEPTION em desenvolvimento e produção, pois evita que erros passem despercebidos.
Boas práticas
Sempre configure o modo de erro para exceções (PDO::ERRMODE_EXCEPTION) ao criar a conexão. Isso garante que você seja notificado de qualquer problema imediatamente. Além disso, evite colocar credenciais diretamente no código; use variáveis de ambiente ou arquivos de configuração fora do diretório público. Por fim, sempre use prepared statements para consultas que envolvam dados fornecidos pelo usuário, mesmo que pareçam seguros.
Referências
- PHP Manual: PDO
- PHP Manual: Conexões com PDO
- PHP Manual: Tratamento de erros com PDO
- PHP Manual: Prepared Statements
- PHP Manual: Drivers PDO (MySQL)
- PHP Manual: Constantes PDO
Exercícios
- Escreva um código PHP que conecte ao banco de dados SQLite em um arquivo chamado 'meu_banco.db' usando PDO, configurando o modo de erro para exceções.
- Explique por que é importante usar PDO em vez de extensões específicas como mysqli.
- Monte um DSN para conectar a um banco PostgreSQL rodando em localhost, porta 5432, banco 'loja', com charset UTF-8.
- Qual é o método para configurar o modo de erro de um objeto PDO para lançar exceções? Dê um exemplo.
- Escreva um código que conecte a um banco MySQL com as credenciais: host='localhost', usuario='admin', senha='123', banco='test', charset='utf8mb4', e configure o modo de erro para exceções e o fetch mode para associativo.
<?php
$dsn = 'sqlite:meu_banco.db';
$opcoes = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
];
try {
$pdo = new PDO($dsn, null, null, $opcoes);
echo "Conectado ao SQLite";
} catch (PDOException $e) {
echo "Erro: " . $e->getMessage();
}
?>
pgsql:host=localhost;port=5432;dbname=loja;charset=utf8
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION). Exemplo: $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
<?php
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8mb4';
$opcoes = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];
$pdo = new PDO($dsn, 'admin', '123', $opcoes);
?>