Utilizando PHP para validar dados passados pelo usuário

Introdução

Este artigo descreve sucintamente o uso das funções Filter do PHP. Estas funções são utilizadas para avaliar e validar dados passados por usuários ou oriundos de outras fontes não seguras.

A referência em português das funções pode ser encontrada em: http://www.php.net/manual/pt_BR/ref.filter.php

Nenhuma dependência é necessária para a execução destas funções, sendo que o comportamento delas pode ser modificado no php.ini pela alteração de “filter.default” e “filter.default_flags”.

Estas funções são um interessante complemento à validação de dados feita no lado cliente, geralmente com JavaScript. Validando os dados no lado do servidor, é possível impedir que usuários mal-intencionados explorem brechas na validação do lado cliente para provocar danos no sistema. Além disso, vários dos filtros existentes simplificam o processo de validação, que geralmente é feito com funções e expressões regulares complexas.

Validando e filtrando strings

A seguir são apresentadas algumas formas de se validar strings, sejam elas números, texto, e-mail ou IP.

Nos exemplos estaremos utilizando a função filter_var(), cuja sintaxe é a seguinte:

filter_var ( mixed $variable [[, int $filter [[, mixed $options ]]]] )

Filtrando números:

$var = filter_var($numero, FILTER_VALIDATE_INT); //retorna o valor de $numero se for inteiro, senão, retorna false

Utilize FILTER_VALIDATE_BOOLEAN para verificar se $numero é um valor booleano (true ou false, 1 ou 0);

Utilize FILTER_VALIDATE_FLOAT para verificar se $numero é do tipo float (decimal) ou não.

Filtrando URL, e-mail e IP:

$var = filter_var($string, FILTER_VALIDATE_URL); //retorna $string se for uma URL, ou false se não for URL. Obs: a URL a ser testada deve conter o protocolo, ou seja, iniciar por http:// ou ftp://

Utilize FILTER_VALIDATE_EMAIL para validar e-mails e FILTER_VALIDATE_IP para validar endereços IP.

Filtrando strings:

Muitas vezes queremos remover tags html e outros tipos de caracteres de strings antes de armazená-las no banco de dados. Para isso podemos utilizar o filtro FILTER_SANITIZE_STRING:

$var = filter_var($string, FILTER_SANITIZE_STRING);//irá retirar tags html de $string

$var = filter_var($string, FILTER_SANITIZE_STRING,FILTER_FLAG_ENCODE_HIGH);//além de retirar tags html, irá transformar alguns caracteres especiais, como letras acentuadas, por exemplo, em seus correspondentes códigos html.

Existe uma ampla gama de outros filtros, além de cada um deles possuir várias opções.

Com eles, é possível aplicar várias formas de filtros e validações em variáveis passadas por usuários, garantindo uma maior segurança no processamento do código PHP.

Outras funções de filtragem e validação

Na seção anterior, vimos a função filter_var(). Porém existem outras funções que podem ser utilizadas para filtrar e validar variáveis, as quais veremos resumidamente a seguir:

filter_has_var ( int $type , string $variable_name )

Verifica se a variável $variable_name é de determinado tipo (GET, POST, COOKIE, SERVER, ENV), e retorna true ou false.

filter_input_array ( int $type [[, mixed $definition ]] )

Obtém múltiplas variáveis e opcionalmente, as filtra.
$tipe pode ser INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV, INPUT_SESSION, ou INPUT_REQUEST.

$definition pode ser entendido pelo exemplo abaixo, retirado de http://www.php.net/manual/pt_BR/function.filter-input-array.php:

error_reporting(E_ALL | E_STRICT);
/* dados recebidos pela página pelo método POST
$_POST = array(
‘product_id’ => ‘libgd<script>’,
‘component’ => ’10′,
‘versions’ => ’2.0.33′,
‘testscalar’ => array(’2′, ’23′, ’10′, ’12′),
‘testarray’ => ’2′,
);
*/

$args = array(//aqui são determinados os filtros que serão apelidados para cada uma das variáveis do POST
‘product_id’ => FILTER_SANITIZE_ENCODED,
‘component’ => array(‘filter’ => FILTER_VALIDATE_INT,
‘flags’ => FILTER_REQUIRE_ARRAY,
‘options’ => array(‘min_range’ => 1, ‘max_range’ => 10)
),
‘versions’ => FILTER_SANITIZE_ENCODED,
‘doesnotexist’ => FILTER_VALIDATE_INT,
‘testscalar’ => array(
‘filter’ => FILTER_VALIDATE_INT,
‘flags’ => FILTER_REQUIRE_SCALAR,
),
‘testarray’ => array(
‘filter’ => FILTER_VALIDATE_INT,
‘flags’ => FILTER_REQUIRE_ARRAY,
)

);

$myinputs = filter_input_array(INPUT_POST, $args);//aqui se aplicam os filtros na variável $_POST

var_dump($myinputs);
echo “n”;
?>

Parece complicado, mas se você estudar os filtros utilizados, facilmente irá compreender o código e poderá compor rotinas de validação e filtragem muito simples e muito poderosas para suas páginas.

O exemplo acima deverá imprimir algo próximo disto:

array(6) {
[["product_id"]]=>
array(1) {
[[0]]=>
string(17) “libgd%3Cscript%3E”
}
[["component"]]=>
array(1) {
[[0]]=>
int(10)
}
[["versions"]]=>
array(1) {
[[0]]=>
string(6) “2.0.33″
}
[["doesnotexist"]]=>
NULL
[["testscalar"]]=>
bool(false)
[["testarray"]]=>
array(1) {
[[0]]=>
int(2)
}
} filter_input ( int $type , string $variable_name [[, int $filter [[, mixed $options ]]]] )

A função acima obtém uma variável e a filtra opcionalmente. Veja o exemplo abaixo:

$search_html = filter_input(INPUT_GET, ‘search’, FILTER_SANITIZE_SPECIAL_CHARS);//pega a variável $_GET, aplica FILTER_SANITIZE_ENCODED em $_GET[['search']] $search_url = filter_input(INPUT_GET, ‘search’, FILTER_SANITIZE_ENCODED);
echo “Você procurou por $search_html.n”;
echo “<a href=’?search=$search_url’>Procure novamente.</a>”;
?>

O código retornado ao navegador é o seguinte:

Você procurou por Me & son.
<a href=’?search=Me%20%26%20son’>Procure novamente.</a>

filter_var_array ( array $data [[, mixed $definition ]] )

Esta função obtém várias variáveis e as filtra, opcionalmente. Muito parecida com a função filter_input_array(), diferenciando-se da mesma pelo fato de que $data pode ser um array definido no código, como no exemplo abaixo:

error_reporting(E_ALL | E_STRICT);
$data = array(//repare que para filter_input_array(), os dados a serem filtrados foram recebidos via POST
‘product_id’ => ‘libgd<script>’,
‘component’ => ’10′,
‘versions’ => ’2.0.33′,
‘testscalar’ => array(’2′, ’23′, ’10′, ’12′),
‘testarray’ => ’2′,
);

$args = array(
‘product_id’ => FILTER_SANITIZE_ENCODED,
‘component’ => array(‘filter’ => FILTER_VALIDATE_INT,
‘flags’ => FILTER_FORCE_ARRAY,
‘options’ => array(‘min_range’ => 1, ‘max_range’ => 10)
),
‘versions’ => FILTER_SANITIZE_ENCODED,
‘doesnotexist’ => FILTER_VALIDATE_INT,
‘testscalar’ => array(
‘filter’ => FILTER_VALIDATE_INT,
‘flags’ => FILTER_REQUIRE_SCALAR,
),
‘testarray’ => array(
‘filter’ => FILTER_VALIDATE_INT,
‘flags’ => FILTER_FORCE_ARRAY,
)

);

$myinputs = filter_var_array($data, $args);

var_dump($myinputs);
echo “n”;
?>

Considerações finais

É muito comum que se recorra à expressões regulares e a outros artifícios quando queremos filtrar e validar dados no PHP.

Essa validação é importante para reduzir o risco de que a validação no lado do cliente falha, é burlada ou não existe, garantindo a integridade e a segurança do sistema.

O filtro, por sua vez é importante para padronizar os dados, principalmente quando estes são inseridos em bancos de dados.

O próprio PHP fornece várias funções específicas para filtrar e validar dados e uma delas são o conjunto de funções Filter, as quais vimos resumidamente neste artigo.

Qual é a sua opinião ou dúvida?