<h2>Fundamentos de Formulários HTML</h2>
<p>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 <code><form></code> com atributos essenciais: <code>method</code> (GET ou POST) e <code>action</code> (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.</p>
<pre><code class="language-html"><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></code></pre>
<p>A validação no lado do cliente com <code>required</code>, <code>type="email"</code> e padrões semelhantes melhora a experiência, mas <strong>nunca confie nela</strong>. Toda validação crítica deve ocorrer no servidor PHP. Use atributos semanticamente corretos (<code>type</code>, <code>name</code>, <code>id</code>) para garantir acessibilidade e facilitar a manipulação posterior dos dados.</p>
<h2>Recebimento e Validação de Dados com PHP</h2>
<p>Quando um formulário é enviado via POST, os dados chegam ao servidor na superglobal <code>$_POST</code>. Antes de qualquer processamento, você deve validar e sanitizar essas informações para evitar SQL injection, XSS e outros ataques.</p>
<pre><code class="language-php"><?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;
}
}
?></code></pre>
<p>Use <code>htmlspecialchars()</code> ou <code>filter_var()</code> para sanitizar. Para banco de dados, prepared statements são obrigatórios:</p>
<pre><code class="language-php">// 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]);</code></pre>
<h2>Upload de Arquivos e Dados Complexos</h2>
<p>Formulários frequentemente precisam lidar com uploads de arquivos. A tag <code><input type="file"></code> requer <code>enctype="multipart/form-data"</code> no formulário. Os arquivos chegam em <code>$_FILES</code>.</p>
<pre><code class="language-html"><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></code></pre>
<p>No servidor, validar tipo, tamanho e renomear o arquivo:</p>
<pre><code class="language-php"><?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!";
}
}
?></code></pre>
<h2>Exibição de Erros e Feedback</h2>
<p>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:</p>
<pre><code class="language-php"><?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></code></pre>
<h2>Conclusão</h2>
<p>Dominando formulários HTML e PHP, você aprendeu: (1) <strong>Estrutura e segurança</strong>: sempre valide e sanitize no servidor, nunca confie no cliente; (2) <strong>Tratamento robusto</strong>: use prepared statements, verify file types via MIME, e implemente feedback claro de erros; (3) <strong>Boas práticas</strong>: reutilize arquivos quando possível, exiba erros contextualizados e proteja contra injeção de código com <code>htmlspecialchars()</code> e filtros.</p>
<p>Esses conceitos formam a base para qualquer aplicação web moderna. Pratique implementando validações complexas e testando casos extremos.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://www.php.net/manual/pt_BR/tutorial.forms.php" target="_blank" rel="noopener noreferrer">Documentação oficial PHP - Formulários</a></li>
<li><a href="https://owasp.org/www-project-top-ten/" target="_blank" rel="noopener noreferrer">OWASP - Top 10 Web Application Security Risks</a></li>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Learn/Forms" target="_blank" rel="noopener noreferrer">MDN Web Docs - Formulários HTML</a></li>
<li><a href="https://phptherightway.com/#security" target="_blank" rel="noopener noreferrer">PHP: The Right Way - Security</a></li>
<li><a href="https://www.php.net/manual/pt_BR/pdo.prepared-statements.php" target="_blank" rel="noopener noreferrer">Documentação PDO - Prepared Statements</a></li>
</ul>