Фильтрация входных данных в PHP

PHPЗдравствуйте!

Сегодня, вкратце, я бы хотел рассказать о фильтрации того бреда, который вводит пользователь в формы на нашем сайте. При этом, использовать регулярные выражения мы лично не будем.

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

Есть сайт. Есть какая-то форма (формы) с кучей полей — типа имени юзера, личного сайта, ящика для e-mail-бомбардировки и т.д. Есть какая-то страница, где отображаются введенные данные (самый банальный пример — страница профиля на любом форуме).

Так вот, если не фильтровать базар то, что вводит юзер, то вместо e-mail’а у него в профиле может возникнуть запись типа «hjashfkasdf», и юзер, естественно, не сможет получить письмо с подтверждением регистрации, рассылку или спам еще что-то.

Дальше — хуже. В текстовых полях (длина которых позволяет) можно использовать html-теги, а это уже грозит тем, что с вашего самописного сайта начнут появляться ссылочки на чужие ресурсы, причем не в поле «URL», а в поле, например, «Имя». А это нам уже сильно не понравится, и с этим мы будем бороться.

Раньше на на фильтрацию бросались силы в виде регулярных выражений (что это за зверь, разжевывать не буду; скажу лишь, что регулярки трудны в освоении, хотя и хороши функционально). В php версии, кажется 5.2, появились функции для фильтрации данных.

Чтобы узнать, есть ли они на вашем хостинге, пишем простой скрипт:

if (function_exists(‘filter_list’))
{
$filters = filter_list(); //получаем список фильтров
foreach ($filters as $filter)
{
echo $filter.»<br>\n»;  //выводим его
}
} else {
echo ‘Извините, у вас функций фильтрации нет';
}

Если фильтры есть, то можно их использовать. Я продемонстрирую вам работу функции filter_var:

$valid = filter_var($not_valid, FILTER);

..где $valid — уже обработанное значение переменной $not_valid с помощью фильтра FILTER. Вместо «FILTER» нужно подставить одно из следующих значений, разбитых на группы:

Группа 1. VALIDATE. Функция filter_var вернет TRUE, если проверка прошла успешно.

  • FILTER_VALIDATE_INT — проверка на целое (integer) число;
  • FILTER_VALIDATE_FLOAT — проверка на дробное;
  • FILTER_VALIDATE_BOOLEAN — проверка на булево;
  • FILTER_VALIDATE_URL — проверка на корректность введенного URL’а;
  • FILTER_VALIDATE_EMAIL — проверка (кто бы мог подумать?) на правильность введенного e-mail;
  • FILTER_VALIDATE_IP — проверка корректности введенного IP-адреса;
  • FILTER_UNSAFE_RAW — своими словами не скажу, толком пользоваться не приходилось, вроде бы фильтрует некий небезопасный текст, а при наборе определенных флагов (о них дальше) удаляет или кодирует определенные символы.

Группа 2. SANITIZE. При использовании фильтров из этой группы, уже не будет возвращаться TRUE или FALSE, а введенный юзером текст просто почистится от ненужных нам символов. Ну, или символы эти перекодируются во что-то безопасное.

  • FILTER_SANITIZE_STRING — по моим наблюдениям, удаляет из строки символы угловых скобок и все, что между ними. По сути, удаляет из введенной строки все HTML-теги;
  • FILTER_SANITIZE_STRIPPED — вроде делает то же самое, точно не скажу;
  • FILTER_SANITIZE_ENCODED — кодирует символы `~!@#$%^&*()=+[{]};:'».?/| в шестнадцатеричный формат;
  • FILTER_SANITIZE_SPECIAL_CHARS — преобразует символы угловых скобок (и еще некоторые) в строки типа «&abc;», короче, говоря проще, HTML-теги не будут удаляться, а будут отображаться просто текстом;
  • FILTER_SANITIZE_EMAIL — уберет из строки все символы, недопустимые в e-mail адресе;
  • FILTER_SANITIZE_URL — уберет из строки все символы, недопустимые в URL’е;
  • FILTER_SANITIZE_NUMBER_INT — оставит в строчке только цифры и знаки плюса/минуса;
  • FILTER_SANITIZE_NUMBER_FLOAT — то же самое, только оставляет еще и точку;
  • FILTER_SANITIZE_MAGIC_QUOTES — аналог функции magic_quotes() в PHP, которая (вроде бы) к шестой версии уже будет считаться устаревшей.

Группа 3. Флаги. Они, строго говоря, не являются отдельной группой параметров, они используются только в сочетании с фильтрами из предыдущих групп. Можно использовать несколько флагов одновременно.

  • FILTER_FLAG_ALLOW_OCTAL (только для фильтров *_INT) — разрешает использовать восьмеричные числа;
  • FILTER_FLAG_ALLOW_HEX (только для фильтров *_INT) — то же самое, с шестнадцатеричными;
  • FILTER_FLAG_STRIP_LOW — режет все символы с ASCII-кодом меньше 32;
  • FILTER_FLAG_STRIP_HIGH — режет все символы с ASCII-кодом больше 127;
  • FILTER_FLAG_ENCODE_LOW — кодирует символы с ASCII-кодом меньше 32;
  • FILTER_FLAG_ENCODE_HIGH — кодирует символы с ASCII-кодом больше 127;
  • FILTER_FLAG_NO_ENCODE_QUOTES — игнорирует одинарные и двойные кавычки;
  • надоело писать, остальные фильтры найдете в описании php, работают аналогично описанным мной, только выполняют другие функции.

Пример (совсем простой, для тех кто в непробиваемом танке и не понял, как срезать все HTML-теги, к примеру):

$san_string = filter_var($_POST[‘username’], FILTER_SANITIZE_STRING);

В результате, в переменной $san_string будет содержаться чисто текст, без всяких HTML-тегов, которых мог напихать коварный юзер при заполнении и отправке формы.

Уже времени что-то много, если кто-то что-то спросит — отвечу с радостью, но завтра. Если что забыл дописать — может допишу, на свежую голову.

Спасибо за внимание.

Фильтрация входных данных в PHP: 4 комментария

  1. chemax

    Хорошая штука, но на сильно загруженных страницах лучше использовать регулярки)

    1. FRUTALITY Автор записи

      Дык эта штука на регулярках основана ведь, в чем разница?)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>