Новый input_filter PHP не читает массивы $ _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, но это просто лишний шаг, так как I $ _GET уже является работающим массивом, поэтому имеет смысл сделать это с помощью этих системных массивов, которые уже существуют.

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

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

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

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

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

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

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

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

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

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

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

Как было предложено 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 в данных запроса. И это просто неправильно. 🙂

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