Материал из Wiki.X-news.org
Перейти к: навигация, поиск

PHP фильтры и их использование

PHP очень легок для изучения - особенно для начинающих программистов. Однако, в результате этого, легко забыть о действительно полезном функционале, предлагаемом PHP, особенно когда речь идет о безопасности скриптов. Дальше я опишу PHP фильтры и покажу, как легко их использовать, увеличивая тем самым безопасность приложения.

Что такое PHP фильтры? Если вы писали любые скрипты предназначенные для публичного использования, вы должно быть знаете что никогда нельзя доверять данным введенным пользователем, а PHP фильтры помогут вам решить эту проблему. PHP фильтры реализованы в расширении PHP Filter Extension. Filter Extension это библиотека правил которые можно использовать для проверки и очистки данных введенных пользователем.

Как реализованы фильтры? PHP фильтры выполняются через 2 функции filter_var() и filter_var_array() и флаги, передаваемые этим функциям. Флаг передаваемый функции определяет, какой фильтр вы хотите использовать.

Есть два типа фильтров для валидации и очистки данных. Фильтры для валидации возвращают первоначальные данные, если они прошли фильтр и false в противоположном случае. Фильтры очистки данных возвращают данные переданные им после удаления нужных символов, не прошедших проверку.

Посмотреть какие фильтры доступны можно с помощью функции filter_list(). Например:

print_r(filter_list());
//выводим на экран...
Array
(
   [0] => int
   [1] => boolean
   [2] => float
   [3] => validate_regexp
   [4] => validate_url
   [5] => validate_email
   [6] => validate_ip
   [7] => string
   [8] => stripped
   [9] => encoded
   [10] => special_chars
   [11] => unsafe_raw
   [12] => email
   [13] => url
   [14] => number_int
   [15] => number_float
   [16] => magic_quotes
   [17] => callback
)

Эти фильтры поддерживаются моим сервером, у вас данные могут быть другими. Рассмотрим несколько примеров, как можно использовать эти фильтры.

Для получения более подробной информации о функциях filter_var() и filter_var_array() обратитесь соответствующим разделам документации PHP

Фильтры для валидации данных Проверка на целое число

Вы можете проверить является ли переменная целым числом используя флаг FILTER_VALIDATE_INT. Если является - функция вернет его. В противном же случае вернется False.

$var = 473;
filter_var($var, FILTER_VALIDATE_INT); //вернет 473
$var = 'hello';
filter_var($var, FILTER_VALIDATE_INT); //вернет FALSE
$var = 71.4;
filter_var($var, FILTER_VALIDATE_INT); //вернет FALSE

Для флага FILTER_VALIDATE_INT можно использовать дополнительные параметры: минимум, максимум и значение по умолчанию. Будьте внимательны при определении массива $options array, заметьте, это многомерный массив.

$var_1 = 73;
$var_2 = 246;
$options = array(
    'options' => array(
       'default' => 3,
       'min_range' => 0,
       'max_range' => 99,
   )
);
filter_var($var_1, FILTER_VALIDATE_INT, $options); //вернет 73
filter_var($var_2, FILTER_VALIDATE_INT, $options); //вернет 3

Обратите внимание, второй вызов filter_var() вернет 3, так как определенно значение по умолчанию в массиве $options.

Проверка на число с плавающей точкой Проверка на число с плавающей точкой происходит так же как и проверка на целое число, только используется флаг FILTER_VALIDATE_FLOAT.

$var_1 = 45.3;
$var_2 = 246;
filter_var($var_1, FILTER_VALIDATE_FLOAT, $options); //вернет 45.3
filter_var($var_2, FILTER_VALIDATE_FLOAT, $options); //вернет 246

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

Проверка адреса электронной почты Вы можете использовать фильтры для проверки более абстрактных типов данных, таких как e-mail.

$var_1 = "test@test.ru";
$var_2 = "какие-то данные, но не e-mail";
filter_var($var_1, FILTER_VALIDATE_EMAIL); //вернет test@test.ru
filter_var($var_2, FILTER_VALIDATE_EMAIL); //вернет FALSE

Однако, этот метод не так хорош, как хорошо написанное регулярное выражение. Так, к примеру, e-mail a@a.a проверку фильтром пройдет, хоть и не должен. Следующее регулярное выражение - более лучшее решение этой проблемы:

$pattern = '/^[^0-9][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[@][a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)*[.][a-zA-Z]{2,4}$/';
$email_1 = 'test@test.ru';
$email_2 = 'a@a.a';
preg_match($pattern, $email_1); // вернет TRUE 
preg_match($pattern, $email_2); //вернет FALSE

Проверка на правильность URL`а Проверка URL происходит несколько сложнее, кроме основного флага, используется несколько дополнительных, которые уточняют что именно проверяется. Вот список этих флагов:

FILTER_FLAG_SCHEME_REQUIRED
FILTER_FLAG_HOST_REQUIRED
FILTER_FLAG_PATH_REQUIRED
FILTER_FLAG_QUERY_REQUIRED

Взглянем на примеры:

$var_1 = 'http://kron0s.com';
$var_2 = 'http://kron0s.com/path/to/some/file';
$var_3 = 'http://kron0s.com/path/to/some/file/?foo=bar';
$var_4 = 'www.kron0s.com';
$var_5 = 'some_file.html';
$var_6 = "/path/to/some/file";
filter_var($var_1, FILTER_VALIDATE_URL); // вернет http://kron0s.com
filter_var($var_1, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED); // вернет FALSE
filter_var($var_2, FILTER_VALIDATE_URL); //вернет  http://kron0s.com/path/to/some/file
filter_var($var_2, FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED); // вернет FALSE
filter_var($var_3, FILTER_VALIDATE_URL); // вернет http://kron0s.com/path/to/some/file/?foo=bar
filter_var($var_4, FILTER_VALIDATE_URL); // вернет FALSE
filter_var($var_5, FILTER_VALIDATE_URL); // вернет FALSE
filter_var($var_6, FILTER_VALIDATE_URL); // вернет FALSE

Проверка правильности IP адреса Валидация IP-адресов осуществляется очень просто. используя флаг FILTER_VALIDATE_IP, у которого есть несколько дополнительных параметров. К примеру, вы можете проверять ipv6 адреса.

FILTER_FLAG_IPV4FILTER_FLAG_IPV6FILTER_FLAG_NO_PRIV_RANGEFILTER_FLAG_NO_RES_RANGE
$var_1 = '192.168.0.1';
$var_2 = '543.152.3.9';
$var_3 = '3ffe:1900:4545:3:200:f8ff:fe21:67cf';
echo filter_var($var_1, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); // вернет 192.168.0.1
echo filter_var($var_2, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); // вернет FALSE
echo filter_var($var_3, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); // вернет 3ffe:1900:4545:3:200:f8ff:fe21:67cf

Заметьте, что 543.152.3.9 вернет false, так как не может быть больше чем 255.255.255.255.

Параметры FILTER_FLAG_NO_PRIV_RANGE и FILTER_FLAG_NO_RES_RANGE позволяют проверить входит ли адрес в диапазон частных или зарезервированных адресов.

PHP фильтры для очистки данных Очистка строк Очистка данных осуществляется так же легко как и валидация. Функция filter_var() просто удаляет нежелательные символы и возвращает новые данные. Небольшой пример:

$var_1 = 'какая-то строка';
$var_2 = '"какая-то строка"';
filter_var($var_1, FILTER_SANITIZE_STRING); //вернет какая-то строка
filter_var($var_2, FILTER_SANITIZE_STRING); //вернет "какая-то строка"

Очистка целых чисел

$var_1 = 123214;
$var_2 = '213h34bh312';
filter_var($var_1, FILTER_SANITIZE_NUMBER_INT); //вернет 123214
filter_var($var_2, FILTER_SANITIZE_NUMBER_INT); //вернет 21334312

Использование своих функций в фильтрах Возможна одна из лучших возможностей функции filter_var() это флаг FILTER_CALLBACK, который позволяет вам определить свои правила функции обратного вызова. Если вы не нашли нужного вам правила, определите свое с помощью этого флага.

function my_rule($str) {
 return str_replace(" ", "+", $str);
}
$var_1 = "некая строка с пробелами";
$options = array(
   'options' => 'my_rule'
);
filter_var($var_1, FILTER_CALLBACK, $options); //вернет "некая+строка+с+пробелами"

Заключение Надеюсь этот пост даст вам новые знания о PHP или освежит вашу память. Для краткости я не стал перечислять все возможные флаги, а описанные мною используются наиболее часто. Если вам интересна более подробная информация об этих и остальных флагах - смотрите соответствующий раздел документации PHP.