Menu

PHP filter_var(): validar e-mail, inteiro, URL e mais

filter_var($value, FILTER_VALIDATE_EMAIL) retorna o valor se ele for válido e false se não for; FILTER_VALIDATE_INT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL e FILTER_VALIDATE_IP funcionam do mesmo jeito. Veja as opções (min_range, default), as flags, os filtros de sanitização e a armadilha do false e do 0.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

filter_var($value, FILTER_VALIDATE_EMAIL) retorna o valor quando ele é um endereço de e-mail válido e false quando não é. Troque o filtro para verificar outros formatos: FILTER_VALIDATE_INT, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL, FILTER_VALIDATE_IP. Sempre compare o resultado com === false.

Dois resultados surpreendem. ada@example é rejeitado porque o domínio não tem ponto, e ' ada@example.com' é rejeitado por causa do espaço inicial, então aplique trim() na entrada antes de validá-la.

Validar um e-mail vindo de um formulário

A mesma verificação atrás de um formulário. Rode, digite um endereço e clique em Check; o bloco roda de novo com a sua entrada em $_POST.

O FILTER_VALIDATE_EMAIL verifica só o formato. nobody@example.com passa, e passaria também um endereço com erro de digitação no domínio. Caracteres fora do ASCII são rejeitados: adä@example.com só passa com FILTER_FLAG_EMAIL_UNICODE, que os permite antes do @, e um domínio como exämple.com falha mesmo com a flag, a menos que você o converta antes para a forma xn--. O único jeito de saber se um endereço funciona é enviar um link de confirmação para ele.

Validar um inteiro, com min_range e max_range

O FILTER_VALIDATE_INT transforma uma string válida num int e rejeita todo o resto. O array de opções adiciona um intervalo e um padrão:

Espaços em volta e um + inicial são aceitos, um zero à esquerda ('042') não, e o resultado para '42' é o inteiro 42, não a string. Fora do intervalo dá false; com a opção default você recebe o padrão em vez de false, o que é prático para coisas como ?page= (veja GETe_GET e _POST). Adicione FILTER_FLAG_ALLOW_HEX ou FILTER_FLAG_ALLOW_OCTAL para aceitar 0x1A ou 0755.

A armadilha do 0 e do false

Um '0' válido retorna o inteiro 0, e 0 é falso. Um if simples o trata como falha:

O mesmo vale para FILTER_VALIDATE_FLOAT ('0.0') e FILTER_VALIDATE_BOOL, em que false é uma resposta válida. É para isso que serve o FILTER_NULL_ON_FAILURE.

Booleanos, floats, URLs e endereços IP

FILTER_VALIDATE_BOOL é o nome do PHP 8; FILTER_VALIDATE_BOOLEAN é o mesmo filtro. Sem FILTER_NULL_ON_FAILURE, 'maybe' retornaria false, impossível de distinguir de 'off'.

O FILTER_VALIDATE_URL verifica se a string tem formato de URL, com qualquer esquema. Isso inclui esquemas que você nunca quer num href:

javascript://comment%0Aalert(1) passa no FILTER_VALIDATE_URL, e um navegador o executa como JavaScript quando o link é clicado, porque o %0A encerra o //comment. Verifique o esquema com parse_url() antes de imprimir a URL de um usuário numa página. Você também pode exigir partes com FILTER_FLAG_PATH_REQUIRED e FILTER_FLAG_QUERY_REQUIRED.

Filtros de sanitização

Filtros de sanitização removem caracteres em vez de dizer sim ou não. Eles servem para normalizar a entrada, não para torná-la segura para impressão:

Olhe a primeira linha: Order #12-345 (x2) vira 12-3452, um número que nunca esteve na entrada, e a terceira linha é um endereço que ninguém digitou. Se você sanitizar, valide o resultado depois. Para tudo o que você imprime no HTML, o htmlspecialchars() na hora da saída é a ferramenta certa (FILTER_SANITIZE_FULL_SPECIAL_CHARS faz o mesmo escape). O FILTER_SANITIZE_STRING está depreciado desde o PHP 8.1; veja htmlspecialchars para o que usar no lugar.

Validar um formulário inteiro com filter_var_array

O filter_var_array() aplica um filtro por chave e retorna um array com todas as chaves que você pediu: o valor filtrado, false quando a validação falhou, ou null quando a chave não existia.

role sumiu: chaves que você não listou são descartadas, o que impede um visitante de adicionar role=admin a um formulário e tê-lo salvo. country é null porque não foi enviado. Num servidor web, filter_input_array(INPUT_POST, $rules) faz o mesmo lendo direto da requisição.

Perguntas frequentes

Como valido um endereço de e-mail no PHP?

Use filter_var($email, FILTER_VALIDATE_EMAIL), que retorna a string do e-mail se for válida e false se não for: if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { /* invalid */ }. Ele verifica só o formato; para saber se o endereço existe, envie um e-mail de confirmação.

Como verifico se uma string é um inteiro no PHP?

filter_var($s, FILTER_VALIDATE_INT) retorna o int para "42", "-7" e " 42 ", e false para "4.2", "42abc" ou "042". Compare com !== false, porque um "0" válido retorna 0, que é falso.

Por que o filter_var retorna false para 0?

Não retorna: filter_var('0', FILTER_VALIDATE_INT) retorna o inteiro 0. O bug está na verificação, if (filter_var(...)), que trata 0 como false. Escreva if (filter_var($v, FILTER_VALIDATE_INT) !== false).

O que substituiu o FILTER_SANITIZE_STRING no PHP 8.1?

Nada diretamente; ele foi depreciado porque o nome prometia uma segurança que ele não dava. Valide a entrada que você espera, guarde-a como está e escape-a ao imprimir com htmlspecialchars(). Se precisar remover tags, use strip_tags().

Qual a diferença entre filter_var e filter_input?

O filter_var() filtra qualquer valor que você passar. filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) lê direto da requisição original, então retorna null quando o parâmetro não existe e ignora qualquer mudança que o seu código tenha feito em $_GET. Os dois recebem os mesmos filtros e opções.

Ilustração das linguagens de programação do Coddy

Aprenda a programar com o Coddy

COMEÇAR