Tratamento de formulários em PHP

Se o PHP tem um trunfo, é o gerenciamento de formulários. Tarefas que outras linguagens precisam de um framework para realizar, o PHP já é capaz de fazer desde o início. Esta aula ensina a habilidade mais prática do desenvolvimento web.

1. Revisão sobre formulários HTML

HTML
<form method="POST" action="process.php">
    <!-- Form fields go here -->
    <button type="submit">Submit</button>
</form>
Atributo Valor Descrição
method GET ou POST GET = recuperar dados, POST = modificar dados
action URL ("" = mesma página) Para onde os dados são enviados
name Nome do campo Obrigatório — O PHP usa isso para acessar o valor
🔥 Erro comum: Cada campo do formulário deve ter um atributo name. Se um campo não tiver o atributo name, o PHP nunca receberá seu valor.


2. Recepção de diferentes tipos de campos

(1) Campos de texto

PHP
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name     = $_POST['name'] ?? '';
    $email    = $_POST['email'] ?? '';
    $password = $_POST['password'] ?? '';
    $bio      = $_POST['bio'] ?? '';
}
?>

<form method="POST" action="">
    <input type="text" name="name" placeholder="Username"><br>
    <input type="email" name="email" placeholder="Email"><br>
    <input type="password" name="password" placeholder="Password"><br>
    <textarea name="bio" placeholder="About yourself"></textarea><br>
    <button type="submit">Register</button>
</form>

(2) Campos de seleção (botão de opção, caixa de seleção, menu suspenso)

▶ Exemplo: Como lidar com campos de seleção

PHP
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $gender = $_POST['gender'] ?? '';
    $skills = $_POST['skills'] ?? [];   // Checkboxes come as an array
    $city   = $_POST['city'] ?? '';

    echo "Gender: {$gender}<br>";
    echo "Skills: " . implode(', ', $skills) . "<br>";
    echo "City: {$city}<br>";
}
?>

<form method="POST" action="">
    <label>Gender:</label>
    <input type="radio" name="gender" value="male"> Male
    <input type="radio" name="gender" value="female"> Female
    <br>

    <label>Skills:</label>
    <input type="checkbox" name="skills[]" value="php"> PHP
    <input type="checkbox" name="skills[]" value="mysql"> MySQL
    <input type="checkbox" name="skills[]" value="js"> JavaScript
    <br>

    <label>City:</label>
    <select name="city">
        <option value="">Choose...</option>
        <option value="beijing">Beijing</option>
        <option value="shanghai">Shanghai</option>
    </select>
    <br>

    <button type="submit">Submit</button>
</form>
▶ Experimente
⚠️ Atenção: Os grupos de caixas de seleção devem usar name="skills[]" (entre colchetes) para que o PHP colete todos os valores marcados em um array. Sem os colchetes, você receberá apenas o último valor marcado.


3. Repreenchimento de formulários (preservando as entradas do usuário)

A pior experiência do usuário é preencher um formulário, clicar em “Enviar”, receber uma mensagem de erro e perder tudo o que digitou. O PHP torna isso extremamente fácil de corrigir:

▶ Exemplo: Formulário com tratamento de erros e repreenchimento

PHP
<?php
$errors = [];
$name = $email = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name  = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');

    if ($name === '') {
        $errors[] = 'Username is required';
    }
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors[] = 'Invalid email format';
    }

    if (empty($errors)) {
        echo "<h3 style='color:green'>Registration successful! Welcome, {$name}!</h3>";
        $name = $email = '';  // Clear fields on success
    } else {
        echo "<ul style='color:red'>";
        foreach ($errors as $e) echo "<li>{$e}</li>";
        echo "</ul>";
    }
}
?>

<form method="POST" action="">
    <input type="text" name="name" placeholder="Username"
           value="<?= htmlspecialchars($name) ?>"><br>
    <input type="email" name="email" placeholder="Email"
           value="<?= htmlspecialchars($email) ?>"><br>
    <button type="submit">Register</button>
</form>
▶ Experimente
💡 Dica: htmlspecialchars() é essencial aqui — ele evita que caracteres como ", < e > na entrada do usuário corrompam seu HTML ou injetem scripts (ataques XSS). Abordaremos esse assunto em detalhes na Lição 18.


4. Repovoamento de botões de opção e caixas de seleção

PHP
<?php
$gender = $_POST['gender'] ?? 'male';
$skills = $_POST['skills'] ?? [];
?>

<!-- Radio buttons: use the checked attribute -->
<input type="radio" name="gender" value="male"
       <?= $gender === 'male' ? 'checked' : '' ?>> Male

<!-- Checkboxes: check with in_array -->
<input type="checkbox" name="skills[]" value="php"
       <?= in_array('php', $skills) ? 'checked' : '' ?>> PHP

<!-- Dropdown: use the selected attribute -->
<select name="city">
    <option value="beijing" <?= $city === 'beijing' ? 'selected' : '' ?>>Beijing</option>
</select>

5. Detecção de envios de formulários

PHP
<?php
// Method 1: Check the request method (recommended)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Process the form
}

// Method 2: Check for the submit button
if (isset($_POST['submit'])) {
    // Process the form
}

// Method 3: Check if any POST data arrived
if (!empty($_POST)) {
    // Process the form
}
?>

6. O padrão PRG (Post-Redirect-Get)

Já enviou um formulário, clicou em “Atualizar” e viu aquela temida caixa de diálogo “Confirmar reenvio do formulário”? O padrão PRG resolve esse problema de vez:

PHP
<?php
// prg.php
session_start();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Process the data
    $name = trim($_POST['name'] ?? '');
    
    // Store a flash message in the session
    $_SESSION['flash_message'] = "Welcome, {$name}!";
    
    // Redirect to the same page with a GET request
    header("Location: " . $_SERVER['PHP_SELF']);
    exit;
}

// Display any flash message
if (isset($_SESSION['flash_message'])) {
    echo "<div style='color:green'>{$_SESSION['flash_message']}</div>";
    unset($_SESSION['flash_message']);
}
?>

<form method="POST" action="">
    <input type="text" name="name" placeholder="Username">
    <button type="submit">Register</button>
</form>
💡 Dica: header("Location: ...") realiza um redirecionamento; exit interrompe o script imediatamente. O fluxo do PRG: POST → processar dados → redirecionar para GET → o usuário atualiza a página GET com segurança, sem envio duplicado.

❓ Perguntas Frequentes

P: Por que minhas caixas de seleção não estão aparecendo no PHP? R: Verifique se o atributo name inclui [] (por exemplo, skills[]). Sem os colchetes, apenas o último valor marcado é enviado. Com name[], o PHP reúne todos eles em um array.

P: Meus formulários continuarão funcionando se o usuário desativar o JavaScript? R: Com certeza. O processamento de formulários em PHP ocorre inteiramente no servidor — não depende de JavaScript de forma alguma. O JavaScript apenas melhora a experiência do usuário (validação do lado do cliente, envios via AJAX), mas a funcionalidade principal funciona mesmo sem ele.

P: header("Location: ...") gera um erro. O que está acontecendo? R: A causa mais comum é a saída antes de header(). Qualquer coisa — um echo, HTML bruto, até mesmo uma linha em branco ou BOM antes da tag <?php — conta como saída. Certifique-se de que header() seja executado antes de qualquer saída e salve seu arquivo como UTF-8 sem BOM.

📖 Resumo

📝 Exercícios

  1. Crie um formulário de cadastro completo com: nome de usuário, e-mail, senha, gênero (botão de opção), interesses (caixas de seleção) e cidade (menu suspenso). Use var_dump() para verificar todos os dados recebidos no momento do envio.
  2. Adicione validação e repreenchimento ao formulário: o nome de usuário não deve estar vazio, o e-mail deve ser válido e o gênero deve ser selecionado. Preserve todas as entradas do usuário quando a validação falhar.
  3. Implementar o padrão PRG: após o registro bem-sucedido, redirecionar para a mesma página e exibir uma mensagem em verde informando “Registro bem-sucedido”.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%