Fundamentos de Formulários HTML
Um formulário HTML é a porta de entrada para qualquer comunicação entre o cliente e o servidor. A estrutura básica utiliza a tag <form> com atributos essenciais: method (GET ou POST) e action (URL de destino). Para projetos reais, sempre use POST ao enviar dados sensíveis, pois é mais seguro que GET, que expõe dados na URL.
<form method="POST" action="processar.php">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="mensagem">Mensagem:</label>
<textarea name="mensagem" id="mensagem" rows="5"></textarea>
<select name="categoria">
<option value="">Selecione uma categoria</option>
<option value="duvida">Dúvida</option>
<option value="reclamacao">Reclamação</option>
</select>
<button type="submit">Enviar</button>
</form>
A validação no lado do cliente com required, type="email" e padrões semelhantes melhora a experiência, mas nunca confie nela. Toda validação crítica deve ocorrer no servidor PHP. Use atributos semanticamente corretos (type, name, id) para garantir acessibilidade e facilitar a manipulação posterior dos dados.
Recebimento e Validação de Dados com PHP
Quando um formulário é enviado via POST, os dados chegam ao servidor na superglobal $_POST. Antes de qualquer processamento, você deve validar e sanitizar essas informações para evitar SQL injection, XSS e outros ataques.
<?php
// processar.php
// Verificar se o formulário foi enviado
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Validar email
$email = isset($_POST['email']) ? trim($_POST['email']) : '';
if (empty($email)) {
$erros[] = "Email é obrigatório";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$erros[] = "Email inválido";
}
// Validar mensagem
$mensagem = isset($_POST['mensagem']) ? trim($_POST['mensagem']) : '';
if (empty($mensagem)) {
$erros[] = "Mensagem é obrigatória";
} elseif (strlen($mensagem) < 10) {
$erros[] = "Mensagem deve ter no mínimo 10 caracteres";
}
// Se não houver erros, processar dados
if (empty($erros)) {
// Sanitizar para banco de dados
$email_seguro = htmlspecialchars($email, ENT_QUOTES, 'UTF-8');
$mensagem_segura = htmlspecialchars($mensagem, ENT_QUOTES, 'UTF-8');
// Aqui você salvaria no banco ou enviaria email
$sucesso = true;
}
}
?>
Use htmlspecialchars() ou filter_var() para sanitizar. Para banco de dados, prepared statements são obrigatórios:
// Exemplo com PDO
$pdo = new PDO('mysql:host=localhost;dbname=meu_banco', 'user', 'password');
$stmt = $pdo->prepare("INSERT INTO contatos (email, mensagem) VALUES (?, ?)");
$stmt->execute([$email, $mensagem]);
Upload de Arquivos e Dados Complexos
Formulários frequentemente precisam lidar com uploads de arquivos. A tag <input type="file"> requer enctype="multipart/form-data" no formulário. Os arquivos chegam em $_FILES.
<form method="POST" action="upload.php" enctype="multipart/form-data">
<input type="file" name="documento" accept=".pdf,.doc,.docx" required>
<input type="file" name="imagem" accept="image/*">
<button type="submit">Enviar</button>
</form>
No servidor, validar tipo, tamanho e renomear o arquivo:
<?php
// upload.php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['documento'])) {
$arquivo = $_FILES['documento'];
$tamanho_max = 5 * 1024 * 1024; // 5MB
// Validações
if ($arquivo['error'] !== UPLOAD_ERR_OK) {
die("Erro no upload: " . $arquivo['error']);
}
if ($arquivo['size'] > $tamanho_max) {
die("Arquivo muito grande");
}
// Verificar tipo MIME real (não apenas extensão)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $arquivo['tmp_name']);
finfo_close($finfo);
$tipos_permitidos = ['application/pdf', 'application/msword'];
if (!in_array($mime_type, $tipos_permitidos)) {
die("Tipo de arquivo não permitido");
}
// Renomear e mover
$nome_seguro = uniqid() . '_' . basename($arquivo['name']);
$destino = 'uploads/' . $nome_seguro;
if (move_uploaded_file($arquivo['tmp_name'], $destino)) {
echo "Arquivo enviado com sucesso!";
}
}
?>
Exibição de Erros e Feedback
A experiência do usuário melhora significativamente quando erros são exibidos próximo aos campos relevantes. Reutilize o mesmo arquivo PHP para formulário e processamento:
<?php
// formulario.php - integrado com processamento
$erros = [];
$dados = [
'email' => '',
'nome' => '',
'categoria' => ''
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Validações (conforme exemplos anteriores)
// Se válido: processar dados
// Se inválido: manter dados para re-exibição
$dados['email'] = $_POST['email'] ?? '';
$dados['nome'] = $_POST['nome'] ?? '';
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Formulário</title>
<style>
.erro { color: red; font-size: 0.9em; }
.campo-erro input { border: 1px solid red; }
</style>
</head>
<body>
<?php if (!empty($erros)): ?>
<div style="background: #fee; padding: 10px; margin-bottom: 20px;">
<?php foreach ($erros as $erro): ?>
<p><?php echo $erro; ?></p>
<?php endforeach; ?>
</div>
<?php endif; ?>
<form method="POST">
<div class="<?php echo isset($erros[0]) ? 'campo-erro' : ''; ?>">
<label>Email:</label>
<input type="email" name="email" value="<?php echo htmlspecialchars($dados['email']); ?>">
</div>
<button type="submit">Enviar</button>
</form>
</body>
</html>
Conclusão
Dominando formulários HTML e PHP, você aprendeu: (1) Estrutura e segurança: sempre valide e sanitize no servidor, nunca confie no cliente; (2) Tratamento robusto: use prepared statements, verify file types via MIME, e implemente feedback claro de erros; (3) Boas práticas: reutilize arquivos quando possível, exiba erros contextualizados e proteja contra injeção de código com htmlspecialchars() e filtros.
Esses conceitos formam a base para qualquer aplicação web moderna. Pratique implementando validações complexas e testando casos extremos.