Pular para o conteúdo
murad.guide

PHP

Capítulo 14

Validação no servidor antes de guardar

6 min de leitura 1.023 palavras 1 gravura

Neste capítulo você vai recusar campos inválidos no PHP e explicar a correção necessária.

Seu ponto de partida

Estude depois do capítulo 13. O exemplo deste capítulo é 14-validacao-servidor, no pacote que acompanha o volume. Copie a pasta inicio para um diretório de prática e preserve o original. A raiz do exemplo é a referência concluída desta etapa. Sua cópia permite experimentar sem perder a referência.

Execute o PHP na raiz da sua cópia com php -S 127.0.0.1:8000 -t public. Abra http://127.0.0.1:8000/. Não abra PHP por duplo clique nem use o servidor de Python. Encerre com Ctrl+C antes de trocar de etapa.

Como praticar

Leia a explicação e digite ou confira o código indicado. Mude uma coisa. Antes de conferir, anote sua previsão. Salve, recarregue e compare. Se não acontecer o esperado, investigue o erro antes de avançar. Cada experiência parte dos valores da referência. Depois de conferir, desfaça somente a mudança desse experimento antes de começar a próxima lição. Você pode parar depois de uma lição e retomar mais tarde.

Recuse um nome vazio

Required ajuda o navegador, mas um pedido pode chegar sem passar por essa interface. O PHP precisa conferir os campos antes de autorizar uma gravação.

Trim tira espaços das pontas. Um nome feito apenas de espaços passa a ser vazio e entra na lista de erros. Nesta etapa, o formulário usa novalidate para você observar diretamente as mensagens do PHP. Isso é uma escolha de prática e não a retirada da validação do servidor.

O programa mantém os valores válidos no formulário. A pessoa corrige o problema sem redigitar todo o conteúdo. As mensagens são texto compreensível, não caminhos internos da máquina.

Faça no seu exemplo

Na área PHP, confira o teste do nome e a lista de erros.

if ($valores["nome"] === "") {
    $erros[] = "Escreva um nome fictício.";
}

Mude uma coisa e preveja

Preencha o nome com três espaços, mantendo e-mail e mensagem fictícios válidos.

Anote o que você acha que vai acontecer antes de salvar e recarregar.

Recarregue e confira

Envie. O PHP deve recusar o nome e manter os outros campos. Nenhum arquivo foi criado.

Se não acontecer

Se a página confirmar o envio, confira trim na leitura e a condição antes da confirmação. Required sozinho não resolve esse pedido.

Confira formato sem prometer existência

Filter_var com FILTER_VALIDATE_EMAIL confere um formato de endereço. Ele não garante que a caixa existe e não envia uma mensagem para testá-la. O exercício continua usando lia@example.invalid.

O programa verifica o resultado com === false para identificar a recusa. Uma comparação estrita confere também o tipo do resultado. Na mensagem, diga o que a pessoa deve corrigir sem afirmar que você verificou a existência do endereço.

Um nome, um e-mail e uma mensagem são campos separados. O erro de um campo não deve apagar automaticamente os valores dos demais.

Faça no seu exemplo

Confira a condição do campo de e-mail.

if (filter_var($valores["email"], FILTER_VALIDATE_EMAIL) === false) {
    $erros[] = "Use o e-mail fictício lia@example.invalid.";
}

Mude uma coisa e preveja

Troque somente o e-mail por texto-sem-arroba.

Anote o que você acha que vai acontecer antes de salvar e recarregar.

Recarregue e confira

Envie. A lista de erros deve mencionar e-mail. Restaure lia@example.invalid e confirme que esse erro deixa de aparecer.

Se não acontecer

Se o programa disser que enviou e-mail, o texto da interface está errado. A etapa somente confere formato e recebe campos locais.

Limite o tamanho contando texto

Maxlength no HTML limita a digitação comum. O PHP mantém seus próprios limites: nome com até 80 caracteres, e-mail com até 254 e mensagem com até 1000. A função tamanho conta pontos de código Unicode, incluindo letras acentuadas, em vez de confundir bytes com letras.

O apoio usa mb_strlen quando a extensão está disponível e uma alternativa com expressão regular UTF-8 quando não está. Essa implementação completa acompanha a etapa; você não precisa instalar uma extensão só para fazer a experiência.

Caracteres visuais podem ter mais de um ponto de código, como alguns emojis. Os limites deste exercício usam pontos de código, e não uma promessa de contar todas as combinações visuais como uma letra. O programa também recusa texto que não esteja em UTF-8.

Faça no seu exemplo

Confira o uso do limite de mensagem no PHP.

if (tamanho($valores["mensagem"]) > 1000) {
    $erros[] = "A mensagem deve ter até 1000 caracteres Unicode.";
}

Mude uma coisa e preveja

Numa cópia, troque somente o limite PHP de 1000 para 10 e envie onze letras simples.

Anote o que você acha que vai acontecer antes de salvar e recarregar.

Recarregue e confira

O PHP deve recusar a mensagem. Envie dez letras e confira a confirmação local. Restaure 1000 ao concluir.

Se não acontecer

Se onze letras forem aceitas, você pode ter alterado apenas maxlength no HTML. Confira a condição executada pelo PHP.

Trecho do resultado de referência do capítulo 14

A captura mostra um trecho da referência concluída. Abra e percorra o exemplo para conferir o restante. Experimentos temporários podem produzir outra aparência; restaure os valores indicados antes de comparar.

Atividades para fazer antes das respostas

Use uma nova cópia do exemplo. Tente aplicar o que aprendeu antes de consultar os comentários.

  1. Envie o formulário vazio e liste as mensagens.

  2. Teste um e-mail sem arroba e depois o fictício previsto.

  3. Reduza o limite do nome para 5 e teste um nome com 6 letras.

Respostas comentadas

Compare sua explicação e o que realmente aconteceu. Outra solução pode funcionar se cumprir o objetivo e preservar o acesso ao conteúdo.

  1. O PHP deve apontar nome, e-mail e mensagem; nada é gravado nesta etapa.

  2. O primeiro formato é recusado; o segundo é aceito como exemplo, sem verificar caixa postal.

  3. O limite no servidor deve recusar seis letras. Restaure 80 depois da experiência.

Quando seguir

Você vê o servidor recusar dados inválidos mesmo quando o navegador não bloqueia o envio. Se ainda precisa de ajuda, repita a experiência pequena antes de avançar.

Consulta opcional

Não é preciso ler os links externos para executar os arquivos fornecidos. Eles servem para consultar detalhes quando você quiser.

O arquivo completo

Referência do exemplo 14-validacao-servidor, reproduzida aqui para que você possa conferir sem sair da página.

apoio.php

<?php
declare(strict_types=1);

function escapar(string $texto): string
{
    return htmlspecialchars($texto, ENT_QUOTES | ENT_SUBSTITUTE, "UTF-8");
}

function campo(array $dados, string $chave): string
{
    $valor = $dados[$chave] ?? "";
    if (!is_string($valor) || preg_match('//u', $valor) !== 1) {
        return "";
    }
    return trim($valor);
}

function tamanho(string $texto): int
{
    if (function_exists("mb_strlen")) {
        return mb_strlen($texto, "UTF-8");
    }
    return preg_match_all('/./us', $texto);
}

public/estilos.css

* { box-sizing: border-box; }
body { margin: 0; background: #f4f7fb; color: #203246;
  font: 1.05rem/1.65 Arial, sans-serif; }
header, main, footer { max-width: 48rem; margin-inline: auto; padding: 1.5rem; }
header { padding-top: 2.5rem; }
h1 { font-size: clamp(1.8rem, 5vw, 2.7rem); line-height: 1.2; }
main { background: #fff; border-radius: .8rem; }
article { border-top: 1px solid #cad4df; padding-block: 1rem; }
a { color: #124e77; text-underline-offset: .2em; }
nav { display: flex; flex-wrap: wrap; gap: 1rem; }
label { display: block; font-weight: bold; }
input:not([type=hidden]), textarea { width: 100%; max-width: 34rem;
  border: 2px solid #718095; border-radius: .35rem; padding: .7rem;
  font: inherit; color: inherit; background: #fff; }
button { font: inherit; background: #124e77; color: white;
  border: 0; border-radius: .35rem; padding: .75rem 1.2rem; cursor: pointer; }
button:hover { background: #103b59; }
.mensagem { white-space: pre-wrap; overflow-wrap: anywhere; }
.erros { color: #8b142c; }
.ok { color: #175c30; font-weight: bold; }
:focus-visible { outline: 3px solid #b04d00; outline-offset: 3px; }
.pular { position: absolute; left: -10000px; }
.pular:focus { position: static; display: block; padding: 1rem; background: white; }
@media (max-width: 35rem) { header,main,footer { padding: 1rem; } }