Hoje em dia não dá mais pra sair conectando no banco com mysqli_connect e senha escrita no meio do código.
Além de inseguro, isso vira uma bagunça quando você precisa mudar de servidor ou separar ambiente de testes e produção.
Neste guia, vou mostrar passo a passo como criar um arquivo de conexão moderno, usando:
- PDO (interface mais segura e flexível para bancos de dados);
- Variáveis de ambiente (para não deixar usuário e senha expostos no código);
- Uma classe de conexão reutilizável, fácil de usar em qualquer projeto.
Objetivo: no final você terá uma classe
Conexaoque retorna um objeto PDO pronto para uso, sem senha exposta no código.
1. Por que evitar a conexão “antiga” em PHP
Um código assim aqui embaixo parece inocente, mas é um problema:
<?php
$servidor = "localhost";
$usuario = "root";
$senha = "123456";
$banco = "meu_banco";
$conexao = mysqli_connect($servidor, $usuario, $senha, $banco);
Problemas:
- Senha exposta no código (qualquer um que tiver acesso ao arquivo vê tudo);
- Dificulta ter ambientes diferentes (local, teste, produção);
mysqli_*é mais limitado e te incentiva a cair em SQL Injection se não tomar cuidado.
Com PDO + variáveis de ambiente, você:
- Esconde credenciais (ficam fora do repositório Git, por exemplo);
- Usa o mesmo código para MySQL, PostgreSQL, SQL Server, etc.;
- Ganha suporte nativo a prepared statements (segurança contra SQL Injection).
2. Estrutura básica do projeto
Uma estrutura simples que já resolve:
/meu-projeto
/config
Conexao.php
/public
index.php
.env
composer.json
vendor/ (criado pelo Composer)
- Arquivos acessados pelo navegador (como
index.php) vão em/public. - Arquivo de conexão e outros configs ficam fora da pasta pública.
- O arquivo
.envguarda variáveis de ambiente.
3. Criando o arquivo .env com os dados do banco
Na raiz do projeto, crie um arquivo chamado .env (sem nome antes do ponto):
DB_DRIVER=mysql
DB_HOST=localhost
DB_PORT=3306
DB_NAME=meu_banco
DB_USER=usuario_do_banco
DB_PASS=senha_super_secreta
DB_CHARSET=utf8mb4
Importante:
- Nunca envie o
.envpara repositórios públicos.- No Git, coloque uma linha com
.envno seu.gitignore.
4. Instalando o PHP Dotenv com Composer
Vamos usar a biblioteca vlucas/phpdotenv para carregar as variáveis do .env.
No terminal, dentro da pasta do projeto, execute:
composer require vlucas/phpdotenv
Isso vai criar/atualizar o composer.json e a pasta vendor/.
5. Criando a classe de conexão com PDO (Conexao.php)
Agora vamos criar o arquivo config/Conexao.php:
<?php
namespace Config;
use PDO;
use PDOException;
use Dotenv\Dotenv;
class Conexao
{
private static ?PDO $instancia = null;
private function __construct()
{
// Evita instanciar a classe diretamente
}
public static function getConexao(): PDO
{
if (self::$instancia === null) {
try {
// Carrega o .env apenas uma vez
$caminhoBase = dirname(__DIR__); // pasta raiz do projeto
$dotenv = Dotenv::createImmutable($caminhoBase);
$dotenv->load();
$driver = $_ENV['DB_DRIVER'] ?? 'mysql';
$host = $_ENV['DB_HOST'] ?? 'localhost';
$porta = $_ENV['DB_PORT'] ?? '3306';
$banco = $_ENV['DB_NAME'] ?? '';
$usuario = $_ENV['DB_USER'] ?? '';
$senha = $_ENV['DB_PASS'] ?? '';
$charset = $_ENV['DB_CHARSET'] ?? 'utf8mb4';
$dsn = "{$driver}:host={$host};port={$porta};dbname={$banco};charset={$charset}";
$opcoes = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
self::$instancia = new PDO($dsn, $usuario, $senha, $opcoes);
} catch (PDOException $e) {
// Em produção, registre o erro em log em vez de exibir na tela
die("Erro ao conectar ao banco de dados: " . $e->getMessage());
}
}
return self::$instancia;
}
}
O que esse código faz
- Usa Singleton: a conexão é criada uma única vez e reaproveitada.
- Carrega o
.envapenas na primeira chamada. - Configura PDO para:
- Lançar exceções em erros (
ERRMODE_EXCEPTION); - Retornar arrays associativos (
FETCH_ASSOC); - Desativar emulação de prepared statements (mais seguro).
- Lançar exceções em erros (
6. Usando a conexão no seu código (exemplo em index.php)
Agora vamos ver como consumir essa conexão dentro de um script.
Crie o arquivo public/index.php:
<?php
require __DIR__ . '/../vendor/autoload.php';
use Config\Conexao;
try {
$pdo = Conexao::getConexao();
$sql = "SELECT id, nome, email FROM usuarios LIMIT 10";
$comando = $pdo->prepare($sql);
$comando->execute();
$usuarios = $comando->fetchAll();
} catch (PDOException $e) {
die("Erro ao buscar usuários: " . $e->getMessage());
}
?>
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Lista de usuários</title>
</head>
<body>
<h1>Usuários</h1>
<?php if (empty($usuarios)): ?>
<p>Nenhum usuário encontrado.</p>
<?php else: ?>
<ul>
<?php foreach ($usuarios as $usuario): ?>
<li>
<?= htmlspecialchars($usuario['nome']) ?> -
<?= htmlspecialchars($usuario['email']) ?>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</body>
</html>
Pontos importantes do exemplo
require __DIR__ . '/../vendor/autoload.php';
Carrega automaticamente todas as classes instaladas via Composer (incluindoConexaoeDotenv).use Config\Conexao;
Usa o namespace definido na classe.htmlspecialchars()
Protege contra XSS ao exibir conteúdo vindo do banco de dados.
7. Erros comuns e como evitar
7.1. “Class Dotenv\Dotenv not found”
Geralmente significa:
- Composer não foi instalado/rodado;
- Autoload não está sendo incluído.
Verifique se:
require __DIR__ . '/../vendor/autoload.php';
está correto e se a pasta vendor/ existe.
7.2. “could not find driver”
Isso quer dizer que a extensão PDO daquele banco não está habilitada no PHP (por exemplo, pdo_mysql).
No php.ini (ou no painel da hospedagem), verifique se as extensões estão habilitadas.
7.3. “Erro ao conectar ao banco de dados: Access denied…”
Verifique:
- Usuário e senha no
.env; - Nome do banco (
DB_NAME); - Host (em hospedagem, às vezes o host não é
localhost).
8. Checklist de segurança para sua conexão
Antes de colocar o site no ar, revise:
- Senha e usuário não aparecem em nenhum arquivo PHP versionado;
- Arquivo
.envestá fora de qualquer repositório público (adicionado ao.gitignore); - PDO configurado com
ERRMODE_EXCEPTION; - Sem
die($e->getMessage())em produção (prefira logar o erro em arquivo ou serviço de log); - Sempre usar prepared statements (
prepare+execute) para consultas com dados do usuário.
9. Vantagens práticas desse padrão
Com essa estrutura você ganha:
- Flexibilidade: se mudar de MySQL para PostgreSQL, só ajusta o
.enve a DSN; - Organização: todo o sistema usa a mesma classe de conexão;
- Segurança: credenciais fora do código, uso de PDO, prepared statements;
- Escalabilidade: fácil crescer o projeto sem virar uma bagunça de
includee variáveis soltas.
Se quiser, você pode adaptar os nomes das variáveis/tabelas para o padrão que você já usa, mas mantendo a ideia central:
Conexão centralizada + PDO +
.env.