Nunca mais você vai usar as variáveis $_GET e $_POST

por adlerparnas

Olá! Pessoal!

Meu nome é Adler Parnas e hoje vou falar de um técnica para acessar, validar e filtrar dados das variáveis $_POST e $_GET no PHP.

Caminhando na minha jornada rumo a Certificação PHP, me deparei com um artigo na PHP Architect, que exemplificava a utilização das funções filter_input e filter_input_array. Tais funções foram inseridas no PHP a partir da versão 5.2 e são uma ótima forma para tratar dados das variáveis $_GET e $_POST deixando seu código mais legível e seguro.

Como é falado no artigo original, é incrível a quantidade de sites/sistemas em PHP com falhas de segurança por  não tratar a entrada de dados pelo usuário. Existe também o tempo gasto para escrever códigos de tratamento dos dados de entrada.

Veja como seu código fica mais limpo e claro utilizando a função filter_input para tratar um parâmetro via GET:


<?php

$user_name = filter_input(INPUT_GET, 'user_name', FILTER_SANITIZE_STRING);

?>

Na página de documentação do PHP, também existe um exemplo utilizando a função filter_input_array, onde é criado um array com as opções de validação do POST esperado pelo programa.

<?php
error_reporting(E_ALL | E_STRICT);

/* data actually came from POST
$_POST = array(
   'product_id'    => 'libgd<script>',
   'component'   => '10',
   'versions'       => '2.0.33',
   'testscalar'    => array('2', '23', '10', '12'),
   'testarray'     => '2',
);
*/
/**
 * Arry com as opções de validação
 */
$args = array(
   '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);

var_dump($myinputs);
?>

O resultado deste tratamento seria:

array
   'product_id'     => string 'libgd%3Cscript%3E' (length=17)
   'component'    => boolean false
   'versions'        => string '2.0.33' (length=6)
   'doesnotexist'  => null
   'testscalar'     => boolean false
   'testarray'      => boolean false

Existem vários tipos de filtros que podem ser utilizados, sendo eles divididos em “dois grupos”, SANITIZE e VALIDATE. Os filtros dos tipo SANITIZE limpam os dados da variável, já os filtros do tipo VALIDATE, retornam FALSE caso o dados não passe pelo filtro.

As funções filter_input e filter_input_array não tratam todos os tipos de dados e nem vão deixar seu programa 100% seguro, mas já é uma boa parte da segurança realizada de forma elegante.

É isso ai galera! Espero que essa dica seja útil a todos vocês e caso tenha dito algo errado, favor me corrijam.

Fontes:

Anúncios

7 Comentários to “Nunca mais você vai usar as variáveis $_GET e $_POST”

  1. Cara,
    Parabéns pelo ótimo post! É bom vermos profissionais em busca da elegância do código e não simplesmente focado na solução de um problema a qualquer custo…

    Parabéns pelo blog também. Ganhou um leitor…

    Só espero que tenha mais posts interessantes como este e o do Javascript orientado a objetos.

    Abraços e sucesso!

  2. Muito bom o blog, principalmente ao inovar um novo método de usar o POST e GET.

  3. Apenas lembrando que essa validação deve ser feita para todas as entradas externas ($_SERVER, $_SESSION).
    Além da elegância, o principal ponto é segurança, pois a função filtra caracteres não esperados.

  4. Quando eu preciso de um formulário, crio um arquivo de texto com uma lista de campos.
    Em seguida, para cada item desta lista, crio um novo arquivo representando o controle do formulário.
    Neste arquivo vão normalmente as seguintes informações:

    control_type=text // o tipo de campo a ser exibido
    control_filter=email // como o campo será filtrado ao ser recebido
    control_target=email // de onde o conteúdo do campo será lido e ao receber, será gravado
    control_required=1 // se o preenchimento é obrigatório
    control_caption=email // a legenda do campo do formulário

    Uma classe de formulário lê a lista do primeiro arquivo e faz a varredura de cada arquivo de controle.
    $formulary = new formulary (‘lista.txt’, $data)
    onde $data são os dados a serem colocados nos campos dos formulários
    $formulary->create()
    isto gera o html.

    $formulary->save()
    isto recolhe os dados e filtra cada tipo de campo

    if (!$formulary->error_msg)
    $data = $formulary->data;
    // transfere os dados recebidos para algum lugar.

    else
    $alert = $formulary->error_msg;
    // transfere o erro para alguma rotina de tratamento.

    Normalmente, quando acontece algum erro, o formulário é exibido novamente, enquanto que se não houverem falhas, uma outra página é exibida.

    A mágica está dentro da classe $formulary, que, para cada tipo de controle, irá chamar uma classe de filtro:
    public function create(){
    global $store;
    foreach ($list as $control_name){
    $control = $store->control->open ($control_name);
    $filter =’filter_’ . $control[‘control_filter’];
    $error_msg =$filter::create ($this, $control);
    }

    Para salvar é um sistema parecido.

    Assim, posso expandir meus filtros, criando novos.
    Tenho uma coleção bem grande deles, para salvar arquivos, filtrar checkboxes, textos, mail, inteiros, html, e mais um mundarel. Inclusive select, verificando se a resposta está dentro das opções válidas.

    Claro que o que estou colocando aqui é um resumo. As classes são bem mais complexas, mas acho que esta é a idéia e, se alguèm quiser desenvolver a partir daí, pode começar. Se quiser os fontes, me mande um email:

    angelobeck [at] floripa.com.br

  5. Opa amigo é SANATIZE ou SANITIZE ?

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: