Introdução
Se você está começando a programar em PHP ou já mexe com a linguagem há algum tempo, cedo ou tarde vai precisar entender como conectar PHP ao MySQL de forma segura e eficiente. A extensão PDO, sigla para PHP Data Objects, é hoje o método mais recomendado para fazer essa integração PHP e banco de dados, substituindo a antiga extensão mysql_ que já foi removida das versões atuais da linguagem.
Neste artigo você vai aprender, na prática, como configurar uma conexão PDO com um banco MySQL, executar consultas com segurança usando prepared statements e evitar erros comuns que costumam travar quem está começando. O conteúdo serve tanto para pequenos scripts quanto como base para sistemas maiores construídos com frameworks como o Laravel.
Vale destacar que dominar essa conexão é a base de praticamente qualquer sistema web que precise salvar dados, seja um blog, um sistema de cadastro de clientes ou uma API. Depois de entender a lógica do PDO, fica muito mais fácil trabalhar com qualquer projeto PHP que envolva banco de dados relacional.
Um dos maiores diferenciais do PDO em relação a métodos antigos de acesso a banco de dados é a possibilidade de trocar o sistema de gerenciamento de banco sem reescrever toda a lógica de acesso aos dados. Se um projeto começa usando MySQL e, por algum motivo, precisa migrar para PostgreSQL no futuro, boa parte do código que usa PDO pode ser aproveitada, bastando ajustar a string de conexão inicial. Essa flexibilidade, somada à segurança dos prepared statements, explica por que o PDO se tornou o padrão de mercado em praticamente todo projeto PHP moderno, inclusive dentro de frameworks populares.
Pré-requisitos / Materiais
Para acompanhar este passo a passo você vai precisar de um ambiente de desenvolvimento local com PHP instalado, como Laragon, XAMPP ou WAMP, todos gratuitos e fáceis de configurar no Windows. Também é necessário ter um servidor MySQL rodando, geralmente já incluído nesses pacotes, além de um editor de código como o VSCode. Um cliente de banco de dados como o HeidiSQL ou o phpMyAdmin ajuda bastante na hora de visualizar as tabelas criadas. Por fim, tenha em mãos as credenciais de acesso ao banco: host, nome do banco de dados, usuário e senha. Se você já trabalha com projetos maiores, também é interessante ter um controle de versão como o Git configurado desde o início, para acompanhar as mudanças no arquivo de conexão e evitar o vazamento acidental de credenciais em repositórios públicos.
Passo a Passo Sequencial
1. Crie o banco de dados de teste. Acesse o phpMyAdmin ou o HeidiSQL e crie um banco chamado, por exemplo, "loja_teste", com uma tabela simples de produtos para os testes seguintes.
CREATE DATABASE loja_teste CHARACTER SET utf8mb4; USE loja_teste; CREATE TABLE produtos ( id INT AUTO_INCREMENT PRIMARY KEY, nome VARCHAR(100) NOT NULL, preco DECIMAL(10,2) NOT NULL );
2. Crie o arquivo de conexão. É uma boa prática manter a conexão PDO em um arquivo separado, chamado por exemplo conexao.php, para ser reutilizado em todo o sistema:
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Erro na conexão: " . $e->getMessage());
}
?>
3. Entenda cada parte da string de conexão. O trecho "mysql:host=$host;dbname=$dbname;charset=utf8mb4" informa ao PDO qual driver usar, o endereço do servidor, o banco de dados de destino e o charset, sendo o utf8mb4 essencial para evitar problemas com acentuação e emojis.
4. Configure o modo de erro corretamente. A linha PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION garante que qualquer erro de consulta lance uma exceção em vez de falhar silenciosamente, o que facilita muito a depuração durante o desenvolvimento.
5. Insira dados com prepared statements. Nunca monte consultas concatenando variáveis diretamente na string SQL, pois isso abre brechas para SQL Injection. O caminho correto é assim:
require "conexao.php";
$stmt = $pdo->prepare("INSERT INTO produtos (nome, preco) VALUES (:nome, :preco)");
$stmt->execute([
"nome" => "Teclado mecânico",
"preco" => 259.90
]);
echo "Produto cadastrado com sucesso!";
6. Busque registros do banco de dados. Para consultas de leitura, o processo é parecido:
$stmt = $pdo->prepare("SELECT * FROM produtos WHERE preco > :valor");
$stmt->execute(["valor" => 100]);
$produtos = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($produtos as $produto) {
echo $produto["nome"] . " - R$ " . $produto["preco"] . "
";
}
7. Atualize e delete registros com segurança. O mesmo padrão de parâmetros nomeados se aplica a comandos UPDATE e DELETE, sempre evitando concatenar valores diretamente na query.
$stmt = $pdo->prepare("UPDATE produtos SET preco = :preco WHERE id = :id");
$stmt->execute(["preco" => 199.90, "id" => 1]);
8. Trate exceções de forma organizada. Envolva operações críticas em blocos try/catch para capturar falhas de conexão ou de consulta sem que o sistema quebre de forma abrupta para o usuário final.
9. Reutilize a conexão em todo o projeto. Em vez de repetir o bloco de conexão em cada arquivo, inclua o conexao.php sempre que precisar acessar o banco, mantendo o código mais limpo e fácil de manter. Em projetos maiores, é comum encapsular essa lógica dentro de uma classe de conexão, aplicando o padrão de projeto Singleton para garantir que apenas uma instância da conexão seja criada durante toda a execução da requisição.
10. Feche a conexão quando necessário. Embora o PHP feche a conexão automaticamente ao final do script, em rotinas muito longas é possível liberar a conexão manualmente definindo a variável como null, o que ajuda a liberar recursos do servidor, especialmente em scripts de processamento em lote que rodam por vários minutos, como rotinas de importação de planilhas.
11. Nunca exponha credenciais diretamente no código versionado. Uma prática recomendada é mover host, usuário e senha do banco de dados para variáveis de ambiente, usando um arquivo .env e uma biblioteca como o phpdotenv. Isso evita que informações sensíveis sejam enviadas acidentalmente para repositórios públicos no GitHub, um erro de segurança surpreendentemente comum mesmo entre desenvolvedores experientes.
Perguntas Frequentes
Qual a diferença entre PDO e mysqli? O PDO funciona com vários bancos de dados diferentes, como MySQL, PostgreSQL e SQLite, usando a mesma sintaxe, enquanto o mysqli é exclusivo para MySQL. Por isso o PDO costuma ser preferido em projetos que podem mudar de banco no futuro.
Prepared statements realmente evitam SQL Injection? Sim, quando usados corretamente com parâmetros nomeados ou posicionais, os prepared statements separam o comando SQL dos dados enviados pelo usuário, impedindo que um valor malicioso altere a estrutura da consulta.
Por que usar utf8mb4 em vez de utf8 na conexão? O utf8mb4 suporta corretamente caracteres especiais, acentuação completa e emojis, enquanto o utf8 tradicional do MySQL tem limitações que podem causar erros de gravação em determinados textos.
É possível usar PDO em projetos Laravel? Sim, o próprio Eloquent, ORM padrão do Laravel, utiliza o PDO por baixo dos panos para se comunicar com o banco de dados, então entender PDO ajuda a compreender melhor como o framework funciona internamente.
O que fazer se a conexão PDO retornar erro de acesso negado? Esse erro geralmente indica usuário, senha ou host incorretos, ou ainda uma permissão insuficiente do usuário do MySQL para acessar aquele banco específico. Verifique as credenciais e, se necessário, confira as permissões (grants) do usuário diretamente no MySQL.
Artigos relacionados: Como prevenir SQL Injection em sistemas PHP; Boas práticas de segurança para aplicações PHP.


