PHP

Como Usar Conexão com MySQL usando PDO em PHP em Produção

8 min de leitura

Como Usar Conexão com MySQL usando PDO em PHP em Produção

Introdução ao PDO: Por que usar? PDO (PHP Data Objects) é uma abstração de banco de dados que oferece uma interface consistente para trabalhar com múltiplos sistemas de gerenciamento de dados. Diferentemente da extensão MySQLi, o PDO permite que você mude de banco de dados (MySQL, PostgreSQL, SQLite) sem reescrever todo o código. É seguro por padrão contra injeção SQL quando usado corretamente com prepared statements, e oferece tratamento robusto de erros. Neste artigo, você aprenderá a conectar-se a um banco MySQL, executar queries seguras e gerenciar transações. Vamos focar em boas práticas profissionais que você usará em produção. Conectando ao MySQL com PDO Estabelecendo a Conexão A conexão é o primeiro passo. O PDO usa a sintaxe de Data Source Name (DSN) para identificar o banco: O atributo é crítico: lança exceções em erros, permitindo tratamento profissional. A linha do charset garante compatibilidade com caracteres especiais em UTF-8. Armazenando em Arquivo de Configuração Em produção, nunca coloque credenciais no

<h2>Introdução ao PDO: Por que usar?</h2>

<p>PDO (PHP Data Objects) é uma abstração de banco de dados que oferece uma interface consistente para trabalhar com múltiplos sistemas de gerenciamento de dados. Diferentemente da extensão MySQLi, o PDO permite que você mude de banco de dados (MySQL, PostgreSQL, SQLite) sem reescrever todo o código. É seguro por padrão contra injeção SQL quando usado corretamente com prepared statements, e oferece tratamento robusto de erros.</p>

<p>Neste artigo, você aprenderá a conectar-se a um banco MySQL, executar queries seguras e gerenciar transações. Vamos focar em boas práticas profissionais que você usará em produção.</p>

<h2>Conectando ao MySQL com PDO</h2>

<h3>Estabelecendo a Conexão</h3>

<p>A conexão é o primeiro passo. O PDO usa a sintaxe de Data Source Name (DSN) para identificar o banco:</p>

<pre><code class="language-php">&lt;?php

$host = &#039;localhost&#039;;

$db = &#039;meu_banco&#039;;

$user = &#039;root&#039;;

$pass = &#039;senha123&#039;;

$charset = &#039;utf8mb4&#039;;

$dsn = &quot;mysql:host=$host;dbname=$db;charset=$charset&quot;;

try {

$pdo = new PDO($dsn, $user, $pass);

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

echo &quot;Conectado com sucesso!&quot;;

} catch (PDOException $e) {

die(&#039;Erro na conexão: &#039; . $e-&gt;getMessage());

}

?&gt;</code></pre>

<p>O atributo <code>ATTR_ERRMODE</code> é crítico: <code>PDO::ERRMODE_EXCEPTION</code> lança exceções em erros, permitindo tratamento profissional. A linha do charset garante compatibilidade com caracteres especiais em UTF-8.</p>

<h3>Armazenando em Arquivo de Configuração</h3>

<p>Em produção, nunca coloque credenciais no código. Crie um arquivo separado:</p>

<pre><code class="language-php">// config/database.php

&lt;?php

return [

&#039;host&#039; =&gt; getenv(&#039;DB_HOST&#039;) ?: &#039;localhost&#039;,

&#039;db&#039; =&gt; getenv(&#039;DB_NAME&#039;) ?: &#039;meu_banco&#039;,

&#039;user&#039; =&gt; getenv(&#039;DB_USER&#039;) ?: &#039;root&#039;,

&#039;pass&#039; =&gt; getenv(&#039;DB_PASS&#039;) ?: &#039;&#039;,

];</code></pre>

<p>E use assim:</p>

<pre><code class="language-php">// index.php

&lt;?php

$config = require &#039;config/database.php&#039;;

$dsn = &quot;mysql:host={$config[&#039;host&#039;]};dbname={$config[&#039;db&#039;]};charset=utf8mb4&quot;;

try {

$pdo = new PDO($dsn, $config[&#039;user&#039;], $config[&#039;pass&#039;]);

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

} catch (PDOException $e) {

die(&#039;Erro: &#039; . $e-&gt;getMessage());

}

?&gt;</code></pre>

<h2>Executando Queries de Forma Segura</h2>

<h3>Prepared Statements: Sua Defesa Contra Injeção SQL</h3>

<p>Prepared statements separam a estrutura SQL dos dados, eliminando a vulnerabilidade de injeção:</p>

<pre><code class="language-php">&lt;?php

// ✗ ERRADO - Vulnerável

$email = $_POST[&#039;email&#039;];

$result = $pdo-&gt;query(&quot;SELECT * FROM usuarios WHERE email = &#039;$email&#039;&quot;);

// ✓ CORRETO - Seguro

$email = $_POST[&#039;email&#039;];

$stmt = $pdo-&gt;prepare(&quot;SELECT * FROM usuarios WHERE email = ?&quot;);

$stmt-&gt;execute([$email]);

$usuario = $stmt-&gt;fetch(PDO::FETCH_ASSOC);

if ($usuario) {

echo &quot;Bem-vindo, &quot; . htmlspecialchars($usuario[&#039;nome&#039;]);

}

?&gt;</code></pre>

<p>Existem duas sintaxes: placeholders posicionais (<code>?</code>) ou nomeados (<code>:email</code>). A versão nomeada é mais legível em queries complexas:</p>

<pre><code class="language-php">&lt;?php

$stmt = $pdo-&gt;prepare(&quot;SELECT * FROM usuarios WHERE email = :email AND status = :status&quot;);

$stmt-&gt;execute([

&#039;:email&#039; =&gt; $_POST[&#039;email&#039;],

&#039;:status&#039; =&gt; &#039;ativo&#039;

]);

$usuario = $stmt-&gt;fetch(PDO::FETCH_ASSOC);

?&gt;</code></pre>

<h3>INSERT, UPDATE e DELETE</h3>

<p>Para operações de modificação, use o mesmo padrão:</p>

<pre><code class="language-php">&lt;?php

// INSERT

$stmt = $pdo-&gt;prepare(&quot;INSERT INTO usuarios (nome, email, senha) VALUES (?, ?, ?)&quot;);

$stmt-&gt;execute([

&#039;João Silva&#039;,

&#039;joao@example.com&#039;,

password_hash(&#039;senha123&#039;, PASSWORD_BCRYPT)

]);

$novoId = $pdo-&gt;lastInsertId();

echo &quot;Usuário criado com ID: $novoId&quot;;

// UPDATE

$stmt = $pdo-&gt;prepare(&quot;UPDATE usuarios SET nome = ?, email = ? WHERE id = ?&quot;);

$stmt-&gt;execute([&#039;João Santos&#039;, &#039;joao.santos@example.com&#039;, 5]);

echo &quot;Linhas afetadas: &quot; . $stmt-&gt;rowCount();

// DELETE

$stmt = $pdo-&gt;prepare(&quot;DELETE FROM usuarios WHERE id = ?&quot;);

$stmt-&gt;execute([5]);

echo &quot;Linhas deletadas: &quot; . $stmt-&gt;rowCount();

?&gt;</code></pre>

<h2>Trabalhando com Resultados e Transações</h2>

<h3>Recuperando Dados com Diferentes Formatos</h3>

<p>O PDO oferece várias formas de buscar dados:</p>

<pre><code class="language-php">&lt;?php

$stmt = $pdo-&gt;prepare(&quot;SELECT id, nome, email FROM usuarios WHERE id &gt; ?&quot;);

$stmt-&gt;execute([10]);

// Um registro como array associativo

$usuario = $stmt-&gt;fetch(PDO::FETCH_ASSOC);

echo $usuario[&#039;nome&#039;];

// Um registro como objeto

$usuario = $stmt-&gt;fetch(PDO::FETCH_OBJ);

echo $usuario-&gt;email;

// Todos os registros como array

$stmt-&gt;execute([10]);

$usuarios = $stmt-&gt;fetchAll(PDO::FETCH_ASSOC);

foreach ($usuarios as $user) {

echo $user[&#039;nome&#039;] . &quot;\n&quot;;

}

// Contando resultados

$stmt-&gt;execute([10]);

$total = $stmt-&gt;rowCount();

echo &quot;Total de usuários: $total&quot;;

?&gt;</code></pre>

<h3>Transações: Garantindo Integridade</h3>

<p>Transações garantem que múltiplas operações sejam executadas como um bloco atômico:</p>

<pre><code class="language-php">&lt;?php

try {

$pdo-&gt;beginTransaction();

// Deduz saldo da conta origem

$stmt = $pdo-&gt;prepare(&quot;UPDATE contas SET saldo = saldo - ? WHERE id = ?&quot;);

$stmt-&gt;execute([100, 1]);

// Adiciona saldo na conta destino

$stmt = $pdo-&gt;prepare(&quot;UPDATE contas SET saldo = saldo + ? WHERE id = ?&quot;);

$stmt-&gt;execute([100, 2]);

// Registra a transferência

$stmt = $pdo-&gt;prepare(&quot;INSERT INTO transferencias (origem, destino, valor) VALUES (?, ?, ?)&quot;);

$stmt-&gt;execute([1, 2, 100]);

$pdo-&gt;commit();

echo &quot;Transferência realizada com sucesso!&quot;;

} catch (PDOException $e) {

$pdo-&gt;rollBack();

die(&quot;Erro na transferência: &quot; . $e-&gt;getMessage());

}

?&gt;</code></pre>

<p>Se qualquer operação falhar, o <code>rollBack()</code> desfaz tudo. Sem transações, você poderia perder dinheiro.</p>

<h2>Conclusão</h2>

<p>Você aprendeu três pilares para trabalhar profissionalmente com MySQL em PHP: <strong>(1)</strong> conectar-se de forma segura usando PDO com tratamento de exceções e armazenamento correto de credenciais; <strong>(2)</strong> executar queries seguras contra injeção SQL através de prepared statements com placeholders; <strong>(3)</strong> recuperar dados em múltiplos formatos e manter integridade com transações.</p>

<p>Coloque isso em prática agora. Crie um pequeno projeto que insira e recupere dados, teste o tratamento de erros e valide suas queries contra injeção. Essa é a base sólida que diferencia profissionais de iniciantes.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://www.php.net/manual/pt_BR/book.pdo.php" target="_blank" rel="noopener noreferrer">Documentação Oficial PDO - PHP.net</a></li>

<li><a href="https://www.php.net/manual/pt_BR/pdo.prepared-statements.php" target="_blank" rel="noopener noreferrer">PDO Prepared Statements</a></li>

<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html" target="_blank" rel="noopener noreferrer">OWASP SQL Injection Prevention</a></li>

<li><a href="https://phptherightway.com/#databases" target="_blank" rel="noopener noreferrer">PHP: The Right Way - Database</a></li>

<li><a href="https://www.sitepoint.com/imperative-vs-declarative-programming-php/" target="_blank" rel="noopener noreferrer">Real PHP Security: PDO and Password Hashing</a></li>

</ul>

Comentários

Mais em PHP

Dominando Formulários HTML e Manipulação de Dados com PHP em Projetos Reais
Dominando Formulários HTML e Manipulação de Dados com PHP em Projetos Reais

Fundamentos de Formulários HTML Um formulário HTML é a porta de entrada para...

Guia Completo de Funções em PHP: Declaração, Parâmetros e Retorno
Guia Completo de Funções em PHP: Declaração, Parâmetros e Retorno

Declaração de Funções em PHP Uma função em PHP é um bloco de código reutilizá...

Guia Completo de Roteamento HTTP em PHP: Criando um Router Simples
Guia Completo de Roteamento HTTP em PHP: Criando um Router Simples

O que é Roteamento HTTP e Por Que Importa Roteamento HTTP é o mecanismo funda...