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.