PHP – Aula 33: Validação e Sanitização de Formulário

Na aula 32 vimos como separar o código em diversas páginas para facilitar o entendimento. Mas aqui iremos continuar a fazer tudo em uma única página para evitar confusão ou complexidade.

Tipos de Validações

Existem dois tipos de validações: client-side e server-side.

  • client-side ou “do lado do cliente”: realizado nos navegadores web dos usuários. Podemos usar validação em HTML5 ou JavaScript. No entanto, a validação do lado do cliente não impede que usuários mal-intencionados enviem dados que possam explorar maliciosamente o aplicativo.
  • server-side ou “do lado do servidor”: valida os dados no servidor web usando PHP. Podemos usar as funções filter_var() e filter_input().

Sanitização e validação de dados do formulário

O processo de captura e exibição dos dados do formulário enviado é bastante simples. Mas devemos nos preocupar com o envio e recepção dos dados.

Sanitização é um termo que significa, mais ou menos, higienizar. Qualquer valor, variável, recebida externamente, de outra página, deve ser higienizada, pois pode haver código malicioso que danificar nosso sistema PHP.

Validação é outro termo que devemos fazer antes do usuário enviar os dados. Exemplo, podemos evitar que um campo obrigatório seja enviado em branco, ou que um campo de telefone contenha letras.

Iremos explicar um pouco, mas temos esses artigos a respeito do assunto também:

Para sanitizar podemos usar as funções filter_var() ou filter_input().

USANDO FILTER_VAR()

Suponha que um formulário envie a idade pela URL, isto é, usando get; podemos evitar que caracteres sejam digitados.

Abaixo, vamos supor que o formulário envia a variável idade=40 pela URL, ou seja, usando método GET. Podemos tratar da seguinte maneira:

$idade =  filter_var($_GET['idade'], FILTER_SANITIZE_NUMBER_INT);

Explicando:

  • filter_var() trata a variável $_GET[‘idade’] recebida do formulário
  • é usado o filtro FILTER_SANITIZE_NUMBER_INT de forma que mesmo que o usuário, por acidente, digite 34r ao invés de 34 o “r” intruso será removido automaticamente.

Há diversos outros filtros: FILTER_VALIDATE_EMAIL, FILTER_SANITIZE_STRING, FILTER_SANITIZE_URL…. clique aqui para ver uma lista de filtros.

USANDO FILTER_INPUT()

filter_input(INPUT_GET, 'pesquisa', FILTER_SANITIZE_SPECIAL_CHARS);

Acima temos:

  • INPUT_GET quer dizer que a variável ‘pesquisa‘ foi recebida pela url, ou seja, método GET. Além de INPUT_GET temos INPUT_POSTINPUT_COOKIEINPUT_SERVER, e INPUT_ENV.
  • pesquisa é uma variável recebida através da URL, ou seja, pelo método GET. Exemplo: http://localhost/meusite/index.php?pesquisa=comprar. Aqui, pesquisa recebe o valor comprar.
  • FILTER_SANITIZE_SPECIAL_CHARS quer dizer que queremos sanitizar caracteres especiais(…SPECIAL_CHARS), tais com %, @, &…. Ao final desse artigo publico uma tabela com as principais flags de sanitização.

Diferenças Entre filter_var() e filter_input()

Vimos no post anterior sobre a função filter_var() quem tem funcionalidade similar à filter_input() mas com pequenas diferenças, tais como:

  • Se uma variável não existir, a função filter_input() retorna null enquanto a função filter_var() retorna uma string vazia e emite uma notificação na tela. A notificação é do tipo: “Notice: Undefined index: term in …\search.php on line 3 string(0)
  • A função filter_input() não obtém os valores atuais de $_GET, $_POST, isto é, ela pega sempre a função passada pela URL. Se tentar alterar o valor colocando no meio do página de código um $_GET[‘email] = ‘outro@email’ não dará certo. filter_var() não tem essa restrição.

Exemplo de Formulário Validado e Sanitizado

Iremos editar o arquivo index.php e enviar(action=”index.php”) para ele mesmo os dados do formulário.

Dentro do arquivo index.php digite essas linhas HTML:

<html>

<body>

  <form action="index.php" method="get">
        <label for="nome">Nome:</label>
        <input type="text" name="nome" /> 
        <br>
        <label for="idade">Idade:</label>
        <input type="text" name="idade" />
        <br>
        <label for="email">Email:</label>
        <input type="email" name="email" />


        <button type="submit">Enviar</button>
  </form>

<?php
       
?>

</body>

</html>

Esse é o resultado:

Se quiséssemos pegar os valores era só usar $_GET[‘nome’] ou $_GET[‘idade’] e $_GET[‘email’]

mas receberíamos os dados sem sanitizá-los ou validá-los.

Abaixo temos as mesmas linhas de cima, mas acrescentamos as variáveis pegando os valores do formulário e sanitizadas.

<html>

<body>

  <form action="index.php" method="get">
        <label for="nome">Nome:</label>
        <input type="text" name="nome" /> 
        <br>
        <label for="idade">Idade:</label>
        <input type="text" name="idade" />
        <br>
        <label for="email">Email:</label>
        <input type="email" name="email" />


        <button type="submit">Enviar</button>
  </form>

<?php
    echo $nome =  filter_var($_GET['nome'], FILTER_SANITIZE_STRING) . "<br>" ;     
    echo $idade = filter_var($_GET['idade'], FILTER_SANITIZE_NUMBER_INT) . "<br>"; 
    echo $email = filter_var($_GET['email'], FILTER_SANITIZE_EMAIL);    
    
?>

</body>

</html>
  • FILTER_SANITIZE_STRING sanitiza strings removendo tags e codificando aspas duplas e simples no estilo HTML, opcionalmente remove ou codifica caracteres HTML especiais. 
  • FILTER_SANITIZE_NUMBER_INT remove todos os caracteres, exceto os dígitos, sinal de mais e menos.
  • FILTER_SANITIZE_EMAIL remova todos os caracteres, exceto letras, dígitos e !#$%&'*+-=?^_`{|}~@.[].

Para conhecer mais filtros clique aqui.

Usando isset()

AVISO: Notice: Undefined index: idade in /var/www/html/meusite/index.php on line

Se iniciar a página verá avisos de variáveis não definidas:

Podemos tratar essa situação de duas formas, usando filter_input() ao invés de filter_var:

.....
echo $nome =  filter_input(INPUT_GET, 'nome', FILTER_SANITIZE_STRING) . "<br>"  ; 
.....

ou usando if com isset() ou filter_has_var()

.....
 if (isset($_GET['idade'])) {
        echo $idade = filter_var($_GET['idade'], FILTER_SANITIZE_NUMBER_INT) . "<br>";  
    } 
.....

Vamos usar essa segunda forma com if e isset()

Usando trim()

Nosso formulário está quase indo bem, mas a variável gravará espaço em branco ao início ou final. É bom tratarmos para ele não pegar esses espaços em branco. Para isso usamos trim(), dessa forma:

<html>

<body>

  <form action="index.php" method="get">
        <label for="nome">Nome:</label>
        <input type="text" name="nome" /> 
        <br>
        <label for="idade">Idade:</label>
        <input type="text" name="idade" />
        <br>
        <label for="email">Email:</label>
        <input type="email" name="email" />


        <button type="submit">Enviar</button>
  </form>

<?php    
if ( isset($_GET['nome']) ) { echo $nome = filter_var(trim($_GET['nome']), FILTER_SANITIZE_STRING) . "<br>" ; } if ( isset($_GET['idade']) ) { echo $idade = filter_var(trim($_GET['idade']), FILTER_SANITIZE_NUMBER_INT) . "<br>"; } if ( isset($_GET['email']) ) { echo $email = filter_var(trim($_GET['email']), FILTER_SANITIZE_EMAIL); }
?>

</body>

</html>

Usando empty() e required

empty que dizer vazio em português.

required que dizer requerido, necessário.

O usuário pode clicar em enviar com os campos vazios e isso não é bom! Iremos usar a função empty() do php e a tag required do html

Clique aqui para ver artigo que falamos sobre a função empty() e a tag html chamada required.

Insira “required” conforme texto alaranjado abaixo no html:

<html>

<body>

  <form action="index.php" method="get">
        <label for="nome">Nome:</label>
        <input type="text" name="nome" required  /> 
        <br>
        <label for="idade">Idade:</label>
        <input type="text" name="idade" required />
        <br>
        <label for="email">Email:</label>
        <input type="email" name="email" required />


        <button type="submit">Enviar</button>
  </form>

<?php    
if ( isset($_GET['nome']) ) { echo $nome = filter_var(trim($_GET['nome']), FILTER_SANITIZE_STRING) . "<br>" ; } if ( isset($_GET['idade']) ) { echo $idade = filter_var(trim($_GET['idade']), FILTER_SANITIZE_NUMBER_INT) . "<br>"; } if ( isset($_GET['email']) ) { echo $email = filter_var(trim($_GET['email']), FILTER_SANITIZE_EMAIL); }
?>

</body>

</html>

Iremos inverter o sentido do empty() usando exclamação, assim: !empty(). Dessa forma ele irá passar somente se a variável não estiver vazia.

Na parte do php altere acrescentando um if dentro do outro: if( !empty($_GET[‘nome’]) ) {….

<html>

<body>

  <form action="index.php" method="get">
        <label for="nome">Nome:</label>
        <input type="text" name="nome" required  /> 
        <br>
        <label for="idade">Idade:</label>
        <input type="text" name="idade" required />
        <br>
        <label for="email">Email:</label>
        <input type="email" name="email" required />


        <button type="submit">Enviar</button>
  </form>

<?php    
if ( isset($_GET['nome']) ) { if( !empty($_GET['nome']) ) { echo $nome = filter_var(trim($_GET['nome']), FILTER_SANITIZE_STRING) . "<br>" ; } } if ( isset($_GET['idade']) ) { if( !empty($_GET['idade']) ) { echo $idade = filter_var(trim($_GET['idade']), FILTER_SANITIZE_NUMBER_INT) . "<br>"; } } if ( isset($_GET['email']) ) { if( !empty($_GET['email']) ) { echo $email = filter_var(trim($_GET['email']), FILTER_SANITIZE_EMAIL); } }
?>

</body>

</html>

Acima criamos uma camada de proteção dentro do HTML com required, outras duas camas dentro do nosso PHP usando isset() e empty().

Usamos if aninhado, isto é, um if dentro do outro.

Conclusão

Vimos aqui tratar, analisando, validando e sanitizando os dados recebidos de um fomrulário.

Deixe uma resposta

O seu endereço de email não será publicado.