PHP new input_filter не читает массивы $_GET или $_POST

В PHP 5.2 была добавлена ​​хорошая функция безопасности, называемая "input_filter", поэтому вместо того, чтобы говорить:

$name = $_GET['name'];

теперь вы можете сказать:

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

и он автоматически санирует вашу строку, есть также:

  • FILTER_SANITIZE_ENCODED
  • FILTER_SANITIZE_NUMBER_INT
  • FILTER_SANITIZE_EMAIL
  • FILTER_SANITIZE_URL

и т.д.. поэтому это очень удобная функция безопасности для использования, и я хочу полностью переключиться на нее.

Проблема в том, что... Я часто манипулирую массивами $_GET и $_POST перед их обработкой, например:

$_ GET ['name'] = '(имя по умолчанию)';

но кажется, что filter_input не имеет доступа к изменениям в $_GET, так как он читает "INPUT_GET", который имеет тип int (?). Было бы неплохо, если бы я мог получить filter_input для чтения $_GET, но:

$name = filter_input ( $_GET, 'name', FILTER_SANITIZE_STRING );

дает мне ошибку:

Warning: filter_input() expects parameter 1 to be long, array given.

Может ли кто-нибудь подумать о том, как я мог:

  • манипулировать источником INPUT_GET (если это так), чтобы я мог изменить его значения, прежде чем filter_input сможет их прочитать.
  • Получить filter_input для чтения $_GET

ADDENDUM:


Богатый спросил: "Почему вы все равно меняете массивы, конечно, вы хотите, чтобы они были входом, а не чем-то, что вы программно вставили".

Это просто удобное место для предварительного ввода переменных, например, для:

  • установить значения по умолчанию (если $_GET ['state'] = '', тогда $_GET ['state'] = 'AL')
  • выполнить ручную обработку (удалить все пробелы и т.д.)
  • (некоторые из них будут выполняться с помощью filter_input)

Тогда я знаю, что к тому времени, когда я получу входящую переменную, она безопасна и действительна. Конечно, я мог бы скопировать массив $_GET в другой массив и обработать массив THAT, но это просто лишний шаг, так как я $_GET уже является работающим массивом, поэтому имеет смысл сделать это с помощью этих системных массивов, которые уже существуют.

Ответ 1

Вы можете вручную заставить его снова прочитать массивы, используя filter_var и filter_var_array

$name = filter_var ( $_GET['name'], FILTER_SANITIZE_STRING );

Ответ 2

Удобный способ сделать это без изменения глобального массива:

if (!($name = filter_input(INPUT_GET, 'name'))) {
    $name = 'default_value';
}

Или используя тернарный оператор:

$name = ($name = filter_input(INPUT_GET, 'name')) ? $name : 'default_value';

Ответ 3

Если вы вручную меняете массив, наверняка вам не нужно санировать его? Почему вы все равно меняете массивы, конечно, вы хотите, чтобы они были входом, а не тем, что вы программно вставили.

Возможно, будет полезно больше кода/контекста.

Ответ 4

Как было предложено Jrngs:

Пропустить программное изменение переменной суперглобального запроса и определить и использовать новые обычные переменные.

Не только быстрее создавать новую переменную, чем получать доступ и модифицировать значение в ассоциативном массиве (массив со строковыми индексами), это также, как правило, способ лучше.

Весь смысл функции filter_input заключается в том, чтобы в конечном итоге УДАЛИТЬ использование суперглобальных переменных, поскольку они являются самой опасной точкой всех скриптов PHP и наиболее частой причиной уязвимостей безопасности (как для XSS, так и для SQL), а также ошибки и путаницу, особенно в крупных проектах.

Например, переменные $_GET и $_REQUEST должны возвращать одно и то же значение для одного и того же ключа:

.../?var=1
var_dump($_GET['var']); ---> string '1' (length=1)
var_dump($_REQUEST['var']); ---> string '1' (length=1)
$_GET['var'] = 2;
var_dump($_GET['var']); ---> int 2
var_dump($_REQUEST['var']; ---> string '1' (length=1)

Не говоря уже о том, что сверхглобальные переменные едва ли имеют смысл в объектно-ориентированном коде.

Поэтому функция filter_input будет получать суперглобальные переменные $_GET/$_ POST/$_ REQUEST, что полностью победит точку этой функции. И вы определенно НЕ ДОЛЖНЫ использовать предложенную функцию filter_var для этого:

filter_var($_GET['var'],FILTER_SANITIZE_STRING); ---> JUST NO!

Функция filter_var была создана для обеспечения фильтрации/дезинфекции для переменных без запроса, а не для такого рода "взлома". Что вы делаете, вы по существу берете фильтры из функции filter_input, которая изначально была создана для обеспечения лучшего и безопасного доступа к данным запроса, полностью обойти эту функцию, получить доступ к данным запроса так же, как filter_input был создан для замены и применения фильтров, предоставляемых filter_input в данных запроса. И это просто неправильно.:)

Ответ 5

Бит INPUT_GET - это всего лишь идентификатор (число), указывающий PHP, что ему нужно получить значение от $_GET.

Если вы хотите использовать filter_input для всего массива, вам нужно пройти через него, отправить каждый ключ массива в filter_input и вернуть результат в $_GET.

Скорее всего, будет просто написать функцию, которая сама санирует, и это также должно позволить вам работать с массивами в массивах (это не выглядит так, как это делает filter_input). В комментариях к документации PHP.net есть пара этих примерных функций, таких как удаление "магических кавычек". См. здесь для примера.

Ответ 6

PHP new input_filter не читает массивы $_GET или $_POST. Если вы переписываете Global (например, $_GET, $_POST), то не переходите на filter_input. Вместо этого используйте filter_var ( $_GET['name'], FILTER_SANITIZE_STRING ), вручную передав переменную.