Quando a gente começa (ou até depois de anos trabalhando com PHP), sempre aparecem aquelas dúvidas “bobas” que ninguém explica direito:
- Como criar um arquivo de conexão realmente seguro e moderno?
- Como usar essa conexão em vários arquivos sem repetir código?
- Como fazer INSERT seguro com PDO?
- Como fazer SELECT com parâmetros sem gambiarra?
Neste guia, vou te mostrar 4 coisas práticas, com código completo, do jeito que você pode usar direto no seu projeto.
1. Arquivo de conexão seguro e moderno com PDO (PHP 8)
A ideia aqui é:
- centralizar os dados de conexão em um lugar só
- usar PDO (mais moderno, flexível e seguro)
- configurar:
- charset
- erros como exceção
- prepared statements reais
1.1. Estrutura mínima de pastas
Você pode começar com algo simples:
meu_projeto/
config/
banco.php
public/
index.php
listar_usuarios.php
salvar_usuario.php
A pasta config/ é onde ficará o arquivo de conexão.
1.2. Arquivo config/banco.php
<?php
declare(strict_types=1);
use PDO;
use PDOException;
/**
* Cria e retorna uma conexão PDO com o banco de dados.
* Em caso de erro, registra log e mostra mensagem genérica.
*/
function criarConexao(): PDO
{
$host = 'localhost';
$banco = 'meu_banco';
$usuario = 'meu_usuario';
$senha = 'minha_senha';
$dsn = "mysql:host={$host};dbname={$banco};charset=utf8mb4";
$opcoes = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // erros viram exceção
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // fetch como array associativo
PDO::ATTR_EMULATE_PREPARES => false, // prepared de verdade
];
try {
return new PDO($dsn, $usuario, $senha, $opcoes);
} catch (PDOException $e) {
// Nunca mostra detalhes do erro para o usuário final
error_log('Erro de conexão com o banco: ' . $e->getMessage());
http_response_code(500);
exit('Erro ao conectar ao banco de dados. Tente novamente mais tarde.');
}
}
Dica: o ideal é não deixar usuário/senha de produção nesse arquivo no servidor.
Em ambiente mais avançado, você pode pegar esses dados de variáveis de ambiente (.env). Mas pra começar, esse padrão já é muito melhor do que espalharmysqli_connectpelo sistema.
2. Como usar essa conexão em qualquer arquivo sem repetir código
Agora que temos a função criarConexao(), usar fica simples:
2.1. Exemplo em public/index.php
<?php
declare(strict_types=1);
require __DIR__ . '/../config/banco.php';
$conexao = criarConexao();
echo 'Conexão funcionando com PDO!';
Reparou?
- Você só inclui o arquivo de conexão uma vez;
- Chama
criarConexao()e recebe um objeto PDO pronto pra usar.
Qualquer outro arquivo que precisar do banco faz o mesmo require e usa a função.
3. INSERT seguro com PDO e prepared statements
Agora vamos para algo que o pessoal erra MUITO: salvar dados do formulário no banco sem segurança.
Nada de montar SQL via concatenação ("INSERT ... '$nome'" direto).
Vamos usar prepared statements com parâmetros nomeados.
3.1. Exemplo: public/salvar_usuario.php
Suponha um formulário enviando nome e email via POST.
<?php
declare(strict_types=1);
require __DIR__ . '/../config/banco.php';
$conexao = criarConexao();
// Captura e trata os dados recebidos
$nome = trim($_POST['nome'] ?? '');
$email = trim($_POST['email'] ?? '');
if ($nome === '' || $email === '') {
exit('Preencha nome e e-mail.');
}
// Opcional: validação simples de e-mail
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
exit('E-mail inválido.');
}
$sql = 'INSERT INTO usuarios (nome, email, criado_em)
VALUES (:nome, :email, NOW())';
$stmt = $conexao->prepare($sql);
$sucesso = $stmt->execute([
':nome' => $nome,
':email' => $email,
]);
if ($sucesso) {
echo 'Usuário cadastrado com sucesso!';
} else {
echo 'Erro ao cadastrar usuário.';
}
Pontos importantes aqui:
- Usamos
trim()e operador??pra tratar$_POST. - Validamos coisas básicas (campo vazio e formato de e-mail).
- Usamos
prepare()+execute()com parâmetros nomeados (:nome,:email). - Evitamos SQL injection sem esforço extra.
4. SELECT com filtro (usando parâmetros) – exemplo de busca
Agora vamos ver um SELECT com busca usando parâmetros.
Exemplo: listar usuários pelo nome (ou parte do nome).
4.1. Exemplo: public/listar_usuarios.php
<?php
declare(strict_types=1);
require __DIR__ . '/../config/banco.php';
$conexao = criarConexao();
// Se vier um termo de busca via GET, usamos. Se não, lista tudo.
$busca = trim($_GET['busca'] ?? '');
if ($busca !== '') {
$sql = 'SELECT id, nome, email, criado_em
FROM usuarios
WHERE nome LIKE :busca
ORDER BY criado_em DESC';
$stmt = $conexao->prepare($sql);
$stmt->execute([
':busca' => '%' . $busca . '%',
]);
} else {
$sql = 'SELECT id, nome, email, criado_em
FROM usuarios
ORDER BY criado_em DESC';
$stmt = $conexao->query($sql);
}
$usuarios = $stmt->fetchAll();
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Lista de usuários</title>
</head>
<body>
<h1>Lista de usuários</h1>
<form method="get">
<input type="text" name="busca" placeholder="Buscar por nome"
value="<?= htmlspecialchars($busca, ENT_QUOTES, 'UTF-8'); ?>">
<button type="submit">Buscar</button>
</form>
<ul>
<?php if (empty($usuarios)): ?>
<li>Nenhum usuário encontrado.</li>
<?php else: ?>
<?php foreach ($usuarios as $usuario): ?>
<li>
<?= htmlspecialchars($usuario['nome'], ENT_QUOTES, 'UTF-8'); ?>
(<?= htmlspecialchars($usuario['email'], ENT_QUOTES, 'UTF-8'); ?>)
</li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
</body>
</html>
Detalhes importantes:
- Quando há termo de busca, usamos
LIKE :buscacom%nos parâmetros. - Usamos
htmlspecialchars()ao exibir dados na tela (pra evitar XSS). - Quando não há busca, podemos usar
query()direto sem parâmetros.
5. Resumão: o básico que deixa o código com cara profissional
Com esses exemplos, você já resolve várias coisas que a galera geralmente faz errado:
- Arquivo de conexão moderno e seguro
criarConexao()com PDO, charset, erro como exceção e log em caso de falha.
- Reuso da conexão
- Em qualquer arquivo:
require '../config/banco.php'; $conexao = criarConexao();
- Em qualquer arquivo:
- INSERT seguro
- Sempre com
prepare()+execute()e parâmetros nomeados.
- Sempre com
- SELECT com filtro
- Usando parâmetros para buscas, nada de concatenar
$_GETdireto na query.
- Usando parâmetros para buscas, nada de concatenar
Se você padronizar seus projetos com essa base, já sai do “PHP gambiarra” e entra num nível muito mais profissional — mesmo em sistemas simples.