PHP para Back-End: Formulários, Sessões e Banco de Dados MySQL

O PHP continua sendo uma das linguagens mais usadas no desenvolvimento back-end, especialmente no mercado brasileiro, onde alimenta desde sites institucionais até grandes portais e lojas virtuais. Se você está começando ou quer consolidar seus conhecimentos, este guia prático cobre os tópicos essenciais para criar aplicações web dinâmicas e seguras com PHP. Vamos explorar desde a manipulação de formulários até a integração com banco de dados MySQL, sempre com exemplos funcionais e boas práticas de segurança.

1. Manipulação de formulários com PHP

O PHP é amplamente utilizado para processar dados enviados por formulários HTML. As superglobais $_POST e $_GET permitem acessar os dados submetidos via método POST ou GET, respectivamente. A escolha entre um ou outro depende do tipo de operação: POST para envio de dados sensíveis ou que alteram estado, GET para buscas e filtros.

Exemplo de formulário HTML:

<form method="POST" action="processar.php">
    <label for="nome">Nome:</label>
    <input type="text" name="nome" id="nome" required>
    <button type="submit">Enviar</button>
</form>

Processamento em PHP com validação:

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $nome = trim($_POST['nome'] ?? '');
    if ($nome === '') {
        echo "O campo nome é obrigatório.";
    } else {
        echo "Olá, " . htmlspecialchars($nome);
    }
}
?>

Sempre sanitize a saída com htmlspecialchars para evitar ataques XSS. Para validações mais avançadas, use filter_var com filtros como FILTER_VALIDATE_EMAIL. Em aplicações reais, considere também a proteção contra CSRF com tokens de sessão.

2. Sessões e Cookies

Sessões permitem manter dados do usuário entre requisições de forma segura, armazenando as informações no servidor. Para iniciar uma sessão em PHP, use session_start() antes de qualquer saída do script. Cookies, por outro lado, armazenam dados no navegador e podem ser usados para preferências ou identificadores de sessão.

<?php
session_start();
$_SESSION['usuario'] = 'joao';
$_SESSION['ultimo_acesso'] = time();

// Cookie seguro: httponly e secure
setcookie('preferencia_tema', 'dark', [
    'expires' => time() + 3600,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax'
]);
?>

Boas práticas incluem regenerar o ID da sessão após o login (session_regenerate_id()), definir um tempo de expiração curto e usar cookies apenas com flags de segurança. Nunca armazene senhas ou dados críticos em cookies sem criptografia.

3. Conexão com MySQL: PDO e mysqli

O PHP oferece duas extensões principais para acesso a MySQL: mysqli (MySQL Improved) e PDO (PHP Data Objects). O PDO é mais flexível por suportar múltiplos bancos de dados (MySQL, PostgreSQL, SQLite etc.) e incentivar o uso de prepared statements, o que aumenta a segurança.

Exemplo com PDO:

<?php
$dsn = 'mysql:host=localhost;dbname=meubanco;charset=utf8mb4';
$usuario = 'root';
$senha = '';
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
];
try {
    $pdo = new PDO($dsn, $usuario, $senha, $options);
    echo "Conectado com sucesso!";
} catch (PDOException $e) {
    // Em produção, registre o erro em log e não exiba detalhes ao usuário
    echo "Erro de conexão: " . $e->getMessage();
}
?>

Exemplo com mysqli orientado a objetos:

<?php
$mysqli = new mysqli('localhost', 'root', '', 'meubanco');
if ($mysqli->connect_error) {
    die("Erro de conexão: " . $mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4');
?>

A escolha entre PDO e mysqli depende do projeto. PDO é recomendado para novos sistemas que possam migrar de banco; mysqli é mais específico para MySQL e pode ser mais performático em alguns casos.

4. CRUD Completo com PHP e MySQL

CRUD (Create, Read, Update, Delete) é a base de qualquer aplicação dinâmica. Abaixo, exemplos de cada operação usando PDO com prepared statements.

Create (INSERT):

<?php
$sql = "INSERT INTO usuarios (nome, email, senha) VALUES (:nome, :email, :senha)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
    'nome' => $nome,
    'email' => $email,
    'senha' => password_hash($senha, PASSWORD_BCRYPT)
]);
?>

Read (SELECT):

<?php
$stmt = $pdo->query("SELECT id, nome, email FROM usuarios ORDER BY nome");
while ($row = $stmt->fetch()) {
    echo $row['nome'] . ' - ' . $row['email'] . '<br>';
}
?>

Update:

<?php
$sql = "UPDATE usuarios SET email = :email WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['email' => $novoEmail, 'id' => $id]);
?>

Delete:

<?php
$sql = "DELETE FROM usuarios WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['id' => $id]);
?>

Sempre utilize prepared statements para evitar SQL injection. Para operações em lote, considere transações com beginTransaction() e commit().

5. Upload de Arquivos

Para fazer upload de arquivos, o formulário deve usar o atributo enctype="multipart/form-data". No PHP, as informações do arquivo enviado ficam disponíveis na superglobal $_FILES.

<form method="POST" enctype="multipart/form-data">
    <input type="file" name="documento" accept=".pdf,.jpg,.png">
    <button type="submit">Enviar</button>
</form>

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['documento'])) {
    $arquivo = $_FILES['documento'];
    
    // Validações de segurança
    $tamanhoMaximo = 2 * 1024 * 1024; // 2 MB
    $extensoesPermitidas = ['jpg', 'jpeg', 'png', 'pdf'];
    $ext = strtolower(pathinfo($arquivo['name'], PATHINFO_EXTENSION));
    
    if ($arquivo['error'] !== UPLOAD_ERR_OK) {
        echo "Erro no upload.";
    } elseif (!in_array($ext, $extensoesPermitidas)) {
        echo "Tipo de arquivo não permitido.";
    } elseif ($arquivo['size'] > $tamanhoMaximo) {
        echo "Arquivo muito grande.";
    } else {
        // Gera nome único para evitar sobrescrita
        $novoNome = uniqid() . '.' . $ext;
        $destino = __DIR__ . '/uploads/' . $novoNome;
        if (move_uploaded_file($arquivo['tmp_name'], $destino)) {
            echo "Upload realizado com sucesso!";
        } else {
            echo "Falha ao salvar o arquivo.";
        }
    }
}
?>

Além da validação no servidor, recomenda-se verificar o tipo MIME real do arquivo com mime_content_type() ou finfo e nunca confiar apenas na extensão. Armazene os arquivos em um diretório fora da raiz pública ou use um script intermediário para servir o conteúdo.

6. Sanitização e Segurança

Segurança é um dos pilares do desenvolvimento back-end. As principais práticas incluem:

  • Sanitização de entrada: Use filter_input e filter_var para validar e-mails, URLs, números etc.
  • Prevenção de XSS: Sempre escape a saída com htmlspecialchars, principalmente ao exibir dados fornecidos pelo usuário.
  • SQL injection: Utilize prepared statements (PDO ou mysqli) em vez de concatenar valores diretamente nas consultas.
  • Hash de senhas: Use password_hash() com bcrypt e password_verify() para autenticação.
  • Proteção contra CSRF: Implemente tokens de sessão em formulários que alteram dados.
<?php
// Exemplo prático de sanitização
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if (!$email) {
    echo "E-mail inválido";
} else {
    // prepared statement para inserir
    $stmt = $pdo->prepare("INSERT INTO contatos (email) VALUES (:email)");
    $stmt->execute(['email' => $email]);
}
?>

Nunca confie em dados enviados pelo cliente. Mesmo com validação no front-end, sempre reforce no servidor. Considere também cabeçalhos de segurança HTTP (Content-Security-Policy, X-Frame-Options etc.) para aumentar a proteção da aplicação.

Organização de Projetos PHP

Uma boa estrutura de diretórios facilita a manutenção e a evolução do sistema. Separe a lógica de apresentação (views) da lógica de negócio (controllers) e do acesso a dados (models). Embora frameworks como Laravel e Symfony já tragam essa organização pronta, em projetos pequenos você pode adotar uma estrutura simples como:

projeto/
├── public/         # raiz do servidor web (index.php, assets)
├── src/            # classes e lógica da aplicação
├── config/         # arquivos de configuração
├── uploads/        # arquivos enviados
└── vendor/         # dependências (se usar Composer)

O uso do Composer para gerenciar dependências é altamente recomendado. Mesmo em projetos simples, ele facilita a instalação de pacotes como PHPMailer, bibliotecas de manipulação de imagens e componentes de autenticação.

Perguntas frequentes

PHP é adequado para iniciantes em back-end?

Sim, PHP tem sintaxe acessível, documentação oficial de qualidade e uma comunidade gigante. É uma ótima porta de entrada para desenvolvimento web, especialmente para quem já conhece HTML e CSS.

Qual a diferença entre PDO e mysqli?

PDO suporta múltiplos bancos de dados (MySQL, PostgreSQL, SQLite etc.) e tem sintaxe consistente. Mysqli é específico para MySQL e oferece suporte a recursos próprios do banco, como chamadas a procedimentos armazenados. Para novos projetos, PDO é geralmente a escolha recomendada.

Preciso usar prepared statements sempre?

Sim, sempre que a consulta envolver dados fornecidos pelo usuário. Prepared statements previnem SQL injection de forma eficaz e também melhoram a performance quando a mesma consulta é executada várias vezes com parâmetros diferentes.

Como proteger uploads de arquivos?

Valide extensão, tamanho, tipo MIME real, e armazene os arquivos com nomes gerados aleatoriamente. Configure permissões adequadas no diretório de uploads e, se possível, sirva os arquivos através de um script que verifique permissões de acesso.

Devo usar um framework?

Para projetos mais complexos, um framework como Laravel ou Symfony pode acelerar o desenvolvimento e garantir boas práticas. Para estudos ou projetos muito simples, o PHP puro já é suficiente e ajuda a entender os fundamentos.

Continue seus estudos de programação com outros tópicos como Python para back-end, HTML e CSS front-end, lógica e cálculos, exercícios de lógica de programação e algoritmos em JavaScript. Bônus de boas-vindas até R$1.500