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 post
ou get
solicitaçã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:
- filtro_input()
- filtro_var()
- filter_input_array()
- filter_var_array()
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 $_POST
variável e queira limpá-los:
- nome
- 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) : array
Linguagem de código: PHP ( php )
A função possui dois parâmetros:
- O
$inputs
parâmetro é uma matriz associativa. Pode ser$_POST
,$_GET
ou uma matriz associativa regular. - O
$fields
parâ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 $fields
ser 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
$fields
e use o filtro correspondente para cada um. Por exemplo, se a regra forstring
, 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 string
regra:
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 $options
dos arrays $fields
e 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 FILTERS
constante. Para torná-lo mais flexível, você pode adicionar um parâmetro e definir seu valor padrão para a FILTERS
constante 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 $inputs
um filtro, por exemplo, FILTER_SANITIZE_STRING
.
Para fazer isso, você pode:
- Primeiro, torne o
$fields
parâmetro opcional e defina seu valor padrão como um array vazio[]
. - Segundo, adicione um parâmetro de filtro padrão.
- Terceiro, se o
$filters
array 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, $inputs
pode 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 $inputs
pode 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 hobbies
item, 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.php
arquivo 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 $input
as 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.