Entrada de limpeza de PHP

Resumo : neste tutorial, você aprenderá a desenvolver uma sanitize()função PHP reutilizável para higienizar entradas.

Introdução à higienização de insumos

Antes de processar dados de fontes não confiáveis, como HTTP postou getsolicitação, você deve sempre limpá-los primeiro.

Limpar a entrada significa remover caracteres ilegais usando técnicas de exclusão, substituição, codificação ou escape.

O PHP fornece uma lista de filtros de limpeza que você pode usar para limpar a entrada de maneira eficaz. As funções a seguir usam esses filtros para limpar a entrada:

Neste tutorial, criaremos uma sanitize()função reutilizável que higieniza as entradas de uma forma mais expressiva.

Defina a função sanitize()

Suponha que você tenha os seguintes campos na $_POSTvariável e queira limpá-los:

  • nome
  • e-mail
  • idade
  • peso
  • pagina inicial

Para fazer isso, você pode definir uma sanitize()função e chamá-la da seguinte forma:

$data = santize($_POST, $fields);Linguagem de código:  PHP  ( php )

A sanitize()função deve ficar assim:

function sanitize(array $inputs, array $fields) : arrayLinguagem de código:  PHP  ( php )

A função possui dois parâmetros:

  • O $inputsparâmetro é uma matriz associativa. Pode ser $_POST, $_GETou uma matriz associativa regular.
  • O $fieldsparâmetro é uma matriz que especifica uma lista de campos com regras.

A sanitize()função retorna uma matriz que contém os dados higienizados.

Deve $fieldsser uma matriz associativa em que a chave é o nome do campo e o valor é a regra para esse campo. Por exemplo:

$fields = [
    'name' => 'string',
    'email' => 'email',
    'age' => 'int',
    'weight' => 'float',
    'github' => 'url',
    'hobbies' => 'string[]'
];Linguagem de código:  PHP  ( php )

Observe que the string[]significa uma matriz de strings.

Para higienizar esses campos:

  • Primeiro, itere $fieldse use o filtro correspondente para cada um. Por exemplo, se a regra for string, o filtro será FILTER_SANITIZE_STRING.
  • Segundo, higienize o campo usando o filtro.

Para obter um filtro baseado na regra de um campo, você pode definir um mapeamento entre as regras com os filtros como este:

const FILTERS = [
    'string' => FILTER_SANITIZE_STRING,
    'string[]' => [
        'filter' => FILTER_SANITIZE_STRING,
        'flags' => FILTER_REQUIRE_ARRAY
    ],
    'email' => FILTER_SANITIZE_EMAIL,
    'int' => [
        'filter' => FILTER_SANITIZE_NUMBER_INT,
        'flags' => FILTER_REQUIRE_SCALAR
    ],
    'int[]' => [
        'filter' => FILTER_SANITIZE_NUMBER_INT,
        'flags' => FILTER_REQUIRE_ARRAY
    ],
    'float' => [
        'filter' => FILTER_SANITIZE_NUMBER_FLOAT,
        'flags' => FILTER_FLAG_ALLOW_FRACTION
    ],
    'float[]' => [
        'filter' => FILTER_SANITIZE_NUMBER_FLOAT,
        'flags' => FILTER_REQUIRE_ARRAY
    ],
    'url' => FILTER_SANITIZE_URL,
];Linguagem de código:  PHP  ( php )

Por exemplo, o seguinte retorna o filtro da stringregra:

FILTER['string']Linguagem de código:  PHP  ( php )

Para higienizar vários campos ao mesmo tempo, você pode usar a filter_var_array()função:

filter_var_array($inputs, $options)Linguagem de código:  PHP  ( php )

O primeiro parâmetro da filter_var_array()função é um array de variáveis ​​a serem filtradas. E o segundo parâmetro é uma matriz de filtros. Por exemplo, deve ficar assim:

$options = [
    'name' => FILTER_SANITIZE_STRING,
    'email' => FILTER_SANITIZE_EMAIL,
    'age' => [
        'filter' => FILTER_SANITIZE_NUMBER_INT,
        'flags' => FILTER_REQUIRE_SCALAR
    ],
    'weight' => [
        'filter' => FILTER_SANITIZE_NUMBER_FLOAT,
        'flags' => FILTER_FLAG_ALLOW_FRACTION
    ],
    'github' => FILTER_SANITIZE_URL,
];Linguagem de código:  PHP  ( php )

Então você precisa retornar isso $optionsdos arrays $fieldse FILTERS. Para fazer isso, você pode usar a array_map()função assim:

 $options = array_map(fn($field) => FILTERS[$field], $fields);Linguagem de código:  PHP  ( php )

O seguinte mostra a sanitize()função:

function sanitize(array $inputs, array $fields): array
{
    $options = array_map(fn($field) => FILTERS[$field], $fields);
    return filter_var_array($inputs, $options);
}Linguagem de código:  PHP  ( php )

Torne a função sanitize() mais flexível

A sanitize()função usa a FILTERSconstante. Para torná-lo mais flexível, você pode adicionar um parâmetro e definir seu valor padrão para a FILTERSconstante assim:

function sanitize(array $inputs, array $fields, array $filters = FILTERS): array
{
    $options = array_map(fn($field) => $filters[$field], $fields);
    return filter_var_array($inputs, $options);
}Linguagem de código:  PHP  ( php )

Além disso, você pode querer higienizar os campos usando $inputsum filtro, por exemplo, FILTER_SANITIZE_STRING.

Para fazer isso, você pode:

  • Primeiro, torne o $fieldsparâmetro opcional e defina seu valor padrão como um array vazio [].
  • Segundo, adicione um parâmetro de filtro padrão.
  • Terceiro, se o $filtersarray estiver vazio, use o filtro padrão.

A sanitize()função ficará parecida com a seguinte:

function sanitize(array $inputs, array $fields = [], int $default_filter = FILTER_SANITIZE_STRING, array $filters = FILTERS): array
{
    if ($fields) {
        $options = array_map(fn($field) => $filters[$field], $fields);
        return filter_var_array($inputs, $options);
    }

    return filter_var_array($inputs, $default_filter);
}Linguagem de código:  PHP  ( php )

Remover espaços em branco de strings

Para remover os espaços em branco de uma string, você usa a trim()função. E para remover os espaços em branco de um array de strings, você usa a array_map()função com a trim()função:

$trimmed_data = array_map('trim', $inputs);Linguagem de código:  PHP  ( php )

No entanto, $inputspode conter itens que não são strings. Para cortar apenas o item de string, você pode usar is_string()a função para verificar se o item é uma string antes de cortá-lo:

$trimmed_data = array_map(function ($item) {
    if (is_string($item)) {
        return trim($item);
    }
    return $item;
}, $inputs);Linguagem de código:  PHP  ( php )

O $inputspode conter um item que é uma matriz de strings. Por exemplo:

$inputs = [
    ...
    'hobbies' => [
        ' Reading',
        'Running ',
        ' Programming '
    ]
]Linguagem de código:  PHP  ( php )

Para cortar as strings do hobbiesitem, você precisa usar uma função recursiva:

function array_trim(array $items): array
{
    return array_map(function ($item) {
        if (is_string($item)) {
            return trim($item);
        } elseif (is_array($item)) {
            return array_trim($item);
        } else
            return $item;
    }, $items);
}Linguagem de código:  PHP  ( php )

Chame array_trim() da função sanitize()

Para chamar a array_trim()função da sanitize()função:

  • Primeiro, adicione um novo parâmetro chamado $trimà sanitize()função e defina seu valor padrão como verdadeiro.
  • Segundo, chame se array_trim()o parâmetro $trim for verdadeiro.

O seguinte mostra a sanitize()função atualizada:

function sanitize(array $inputs, array $fields = [], int $default_filter = FILTER_SANITIZE_STRING, array $filters = FILTERS, bool $trim = true): array
{
    if ($fields) {
        $options = array_map(fn($field) => $filters[$field], $fields);
        $data = filter_var_array($inputs, $options);
    } else {
        $data = filter_var_array($inputs, $default_filter);
    }

    return $trim ? array_trim($data) : $data;
}Linguagem de código:  PHP  ( php )

Junte tudo

O seguinte mostra o sanitization.phparquivo completo com FILTERS, array_trim()e sanitize()funções:

const FILTERS = [
    'string' => FILTER_SANITIZE_STRING,
    'string[]' => [
        'filter' => FILTER_SANITIZE_STRING,
        'flags' => FILTER_REQUIRE_ARRAY
    ],
    'email' => FILTER_SANITIZE_EMAIL,
    'int' => [
        'filter' => FILTER_SANITIZE_NUMBER_INT,
        'flags' => FILTER_REQUIRE_SCALAR
    ],
    'int[]' => [
        'filter' => FILTER_SANITIZE_NUMBER_INT,
        'flags' => FILTER_REQUIRE_ARRAY
    ],
    'float' => [
        'filter' => FILTER_SANITIZE_NUMBER_FLOAT,
        'flags' => FILTER_FLAG_ALLOW_FRACTION
    ],
    'float[]' => [
        'filter' => FILTER_SANITIZE_NUMBER_FLOAT,
        'flags' => FILTER_REQUIRE_ARRAY
    ],
    'url' => FILTER_SANITIZE_URL,
];

/**
* Recursively trim strings in an array
* @param array $items
* @return array
*/
function array_trim(array $items): array
{
    return array_map(function ($item) {
        if (is_string($item)) {
            return trim($item);
        } elseif (is_array($item)) {
            return array_trim($item);
        } else
            return $item;
    }, $items);
}

/**
* Sanitize the inputs based on the rules an optionally trim the string
* @param array $inputs
* @param array $fields
* @param int $default_filter FILTER_SANITIZE_STRING
* @param array $filters FILTERS
* @param bool $trim
* @return array
*/
function sanitize(array $inputs, array $fields = [], int $default_filter = FILTER_SANITIZE_STRING, array $filters = FILTERS, bool $trim = true): array
{
    if ($fields) {
        $options = array_map(fn($field) => $filters[$field], $fields);
        $data = filter_var_array($inputs, $options);
    } else {
        $data = filter_var_array($inputs, $default_filter);
    }

    return $trim ? array_trim($data) : $data;
}Linguagem de código:  PHP  ( php )

Use a função sanitize()

Veja a seguir como usar a sanitize()função para higienizar dados usando $inputas regras de higienização especificadas em $fields:

<?php

require  __DIR__ . '/sanitization.php';

$inputs = [
    'name' => 'joe<script>',
    'email' => '[email protected]</>',
    'age' => '18abc',
    'weight' => '100.12lb',
    'github' => 'https://github.com/joe',
    'hobbies' => [
        ' Reading',
        'Running ',
        ' Programming '
    ]
];

$fields = [
    'name' => 'string',
    'email' => 'email',
    'age' => 'int',
    'weight' => 'float',
    'github' => 'url',
    'hobbies' => 'string[]'
];

$data = sanitize($inputs,$fields);

var_dump($data);Linguagem de código:  PHP  ( php )

Saída:

Array
(
    [name] => joe
    [email] => [email protected]
    [age] => 18
    [weight] => 100.12
    [github] => https://github.com/joe
    [hobbies] => Array
        (
            [0] => Reading
            [1] => Running
            [2] => Programming
        )

)Linguagem de código:  PHP  ( php )

Neste tutorial, você aprendeu como desenvolver uma sanitize()função PHP reutilizável do zero.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *