Вы находитесь на странице: 1из 10

Лекции курса PHP7 + MySQL с нуля

(краткое содержание)

ЛЕКЦИЯ 44. ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ PHP. ФИЛЬТРАЦИЯ


ДАННЫХ

Основы
При создании web-приложений необходимо учитывать особенности
обеспечения безопасности как самого приложения, так и пользователей,
использующих его. Так, одной из проблем безопасности является момент ввода и
получения пользовательских данных, которые могут содержать в себе, например,
вредоносный код в виде вводимого в поля формы текста (инъекции).
Для обеспечения безопасности используются два подхода для обработки
данных:
- очистка данных, которая проверяет поступающую информацию и очищает ее
от опасных или подозрительных кусков информации;
- проверка данных, осуществляющая проверку поступающих данных и
обеспечивает подтверждение передачи или отказ в ней.
Эти подходы можно рассмотреть на примерах:
1) Предположим, что пользователю необходимо отправить запрос в виде
числового значения методом GET. При этом, пользователь в поле ввода
информации мог по ошибке или со злым умыслом добавить дополнительные
символы, например, <>. При поступлении со стороны пользователя, запрос
обрабатывается специальными фильтрами, которые исключают из запроса
символы, не соответствующие требованию числовых типов и в сценарий поступает
уже числовой тип. Такой способ называется фильтрацией.
2) В поле ввода электронной почты формат записи должен соответствовать
типу example@email.com, т. е. должен содержать буквы английского алфавита,
либо арабские цифры и ряд допустимых символов, например «.», «-» и т. п. до знака
«@», затем сам знак «@», после, опять же, буквы английского алфавита,
допустимые символы и арабские цифры, затем знак «.» и имя домена, содержащее
арабские цифры или буквы английского алфавита. При этом, пользователь может
ввести в имени получателя запрещенные в адресах электронной почты символы. В
таких случаях функции поступающей информации проверят адрес на соответствие
требованиям и либо отправят его в сценарий, либо откажут, что, обычно, приводит
к уведомлению пользователя о неверно введенном пароле.

Основные способы фильтрации и проверки


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

1
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

а) mixed filter_var(mixed $variable [, int $filter = FILTER_DEFAULT, mixed $options]);


б) mixed filter_var_array(array $data [, mixed $definition, bool $add_empty = true]);
в) mixed filter_input(int $type, string $variable_name [, int $filter = FILTER_DEFAULT,
mixed $options]);
г) mixed filter_input_array(int $type [, mixed $definition, bool $add_empty = true).

Варианты фильтрации данных


Перед тем, как перейти к подробному рассмотрению указанных функций, стоит
рассмотреть, какие же варианты фильтрации предоставляют они в качестве
параметров $filter и $definition.
Фильтры проверки данных:
1) FILTER_VALIDATE_BOOLEAN – возвращает true для значений (1, true, on, yes),
иначе возвращает false. Имеет параметр $options: default, определяющий значение
поступающего аргумента на выходе. Имеет флаг FILTER_NULL_ON_FAILURE,
определяющий, что false будет возвращено только для значений (0, false, off, no), а
null будет возвращен для любых небулевых значений.
2) FILTER_VALIDATE_DOMAIN – проверяет корректность длины меток имен
домена. Проверяет имена на соответствие стандартам RFC. Флаг
FILTER_FLAG_HOSTNAME добавляет возможность проверять имена хостов,
содержащих только буквы, цифры и тире. Также есть опциональный параметр
default.
3) FILTER_VALIDATE_EMAIL – проверяет корректность email в соответствии с
требованиями RFC 822. Флаг FILTER_FLAG_EMAIL_UNICODE разрешает Unicode-
символы локальной части адреса email. Также имеет опциональный параметр
default.
4) FILTER_VALIDATE_FLOAT – проверяет отношение числа к вещественному типу.
Флаг FILTER_FLAG_ALLOW_THOUSAND допускает использование символа запятой в
качестве разделителя между тысячными разрядами (XXX,XXX,XXX.XXX).
Содержит опциональные параметры default и decimal. Decimal определяет тип
разделителя между целой и дробной частью числа.
5) FILTER_VALIDATE_INT – проверяет отношение числа к целочисленному типу и
его вхождение в заданный дополнительными параметрами min_range и max_range
диапазон. При необходимости возвращает default-значение. Флаги
FILTER_FLAG_ALLOW_OCTAL и FILTER_FLAG_ALLOW_HEX устанавливают отношению
числа к восьмеричной и шестнадцатеричной системам исчисления соответственно.
6) FILTER_VALIDATE_IP – проверяет корректность IP-адреса. При установке
флагов FILTER_FLAG_IPV4, FILTER_FLAG_IPV6, FILTER_FLAG_NO_PRIV_RANGE,
FILTER_FLAG_NO_RES_RANGE, проверяет на соответствие протоколам IPv4, IPv6, и на
вхождение в частные и зарезервированные диапазоны соответственно. Содержит
default.
7) FILTER_VALIDATE_MAC – проверяет корректность MAC-адреса. Имеет default-
параметр.
8) FILTER_VALIDATE_REGEXP – проверяет на соответствие регулярному
выражению и имеет default-параметр.
9) FILTER_VALIDATE_URL – проверяет корректность в качестве URL-адреса с
поддержкой дополнительных флагов: FILTER_FLAG_SCHEME_REQUIRED,
FILTER_FLAG_HOST_REQUIRED, FILTER_FLAG_PATH_REQUIRED и
FILTER_FLAG_QUERY_REQUIRED, требующими наличия в проверяемом адресе

2
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

протокола, имени хоста, пути и параметров, соответственно. Содержит default-


параметр.
Перед тем, как перейти к фильтрам очистки данных, стоит заметить, что они
отличаются от фильтров проверки отсутствием в них опциональных параметров по
причине того, что на выходе фильтра остается исходная строка, прошедшая
модификацию в соответствии с выбранным типом очистки.
Фильтры очистки данных:
1) FILTER_SANITIZE_EMAIL - удаляет все символы, кроме букв, цифр и «!#$%&'*+-
=?^_`{|}~@.[]»;
2) FILTER_SANITIZE_ENCODED - кодирует строку в формат URL, при
необходимости удаляет или кодирует специальные символы. В качестве флагов
устанавливаются следующие:
- FILTER_FLAG_STRIP_LOW – удаляет символы, код которых меньше 32;
- FILTER_FLAG_STRIP_HIGH - удаляет символы, код которых больше 127;
- FILTER_FLAG_STRIP_BACKTICK – удаляет символы обратных кавычек «`»;
- FILTER_FLAG_ENCODE_LOW - кодирует все символы, код которых меньше 32;
- FILTER_FLAG_ENCODE_HIGH - кодирует все символы, код которых больше 127.
3) FILTER_SANITIZE_MAGIC_QUOTES – экранирует строку с помощью слешей
(экранируются символы «’”|NUL»). Аналог функции addslashes(), которая будет
рассмотрена в этом уроке далее.
4) FILTER_SANITIZE_NUMBER_FLOAT - удаляет все символы, кроме цифр, +- и, при
необходимости, «.,eE». В результате входящий аргумент на выходе принимает
вещественный тип. Применяются следующие флаги:
- FILTER_FLAG_ALLOW_FRACTION - разрешает наличие точки (.) в качестве
десятичного разделителя в числах;
- FILTER_FLAG_ALLOW_THOUSAND - разрешает наличие запятой (,) в качестве
разделителя тысяч в числах;
- FILTER_FLAG_ALLOW_SCIENTIFIC - разрешает наличие e и E для научных нотаций
чисел.
5) FILTER_SANITIZE_NUMBER_INT - удаляет все символы, кроме цифр и знаков
плюса и минуса. Функция фильтрации возвращает целочисленный тип.
6) FILTER_SANITIZE_SPECIAL_CHARS - экранирует HTML-символы «'"<>&» и
символы с ASCII-кодом, меньшим 32, при необходимости удаляет или кодирует
остальные специальные символы. Может принимать флаги FILTER_FLAG_STRIP_LOW,
FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_HIGH,
рассмотренные в пункте 2, в фильтре FILTER_SANITIZE_ENCODED.
7) FILTER_SANITIZE_FULL_SPECIAL_CHARS - эквивалентно вызову функции
htmlspecialchars() с установленным параметром ENT_QUOTES, которая также будет
рассмотрена далее. Кодирование кавычек может быть отключено с помощью
установки флага FILTER_FLAG_NO_ENCODE_QUOTES.
8) FILTER_SANITIZE_STRING - удаляет теги, при необходимости удаляет или
кодирует специальные символы. Принимает следующие флаги:
FILTER_FLAG_NO_ENCODE_QUOTES, FILTER_FLAG_STRIP_LOW, FILTER_FLAG_STRIP_HIGH,
FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_LOW, FILTER_FLAG_ENCODE_HIGH,
FILTER_FLAG_ENCODE_AMP, среди которых не рассмотрен только
FILTER_FLAG_ENCODE_AMP, кодирующий символ амперсанда «&».
9) FILTER_SANITIZE_URL - удаляет все символы, кроме букв, цифр и «$-
_.+!*'(),{}|\\^~[]`<>#%";/?:@&=».

3
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

10) FILTER_UNSAFE_RAW – фильтр является псевдонимом FILTER_DEFAULT и по


умолчанию бездействует. При использовании флагов FILTER_FLAG_STRIP_LOW,
FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_BACKTICK, FILTER_FLAG_ENCODE_LOW,
FILTER_FLAG_ENCODE_HIGH, FILTER_FLAG_ENCODE_AMP удаляет или кодирует (в
зависимости от флага) специальные символы.
Теперь, рассмотрев все возможные фильтры, которые используются в ранее
рассмотренных функциях, можно перейти к изучению непосредственно функций.

Функция filter_var()
Синтаксис функции:
mixed filter_var(mixed $variable [, int $filter = FILTER_DEFAULT, mixed $options])
Функция принимает следующие параметры:
- $variable – аргумент-переменная, которая будет подвергнута фильтрации;
- $filter – параметр-фильтр, принимающий любое из возможных значений,
указанных ранее в этом уроке (по умолчанию принимает значение FILTER_DEFAULT,
которое не предпринимает никаких действий по фильтрации данных);
- $options – аргумент, который может принимать как ассоциативный массив
параметров, так и логическое выражение «ИЛИ», которые содержат как флаги
фильтрации, так и параметры-опции для фильтров проверки.

Функция filter_var_array()
Синтаксис функции:
mixed filter_var_array(array $data [, mixed $definition, bool $add_empty = true])
Функция принимает следующие параметры:
- $data – ассоциативный массив аргументов-параметров, где ключами массива
выступают имена переменных;
- $definition – ассоциативный массив, содержащий параметры фильтрации, в
котором ключом выступает имя соответствующей аргумента-переменной, а
значением либо тип фильтра, либо ассоциативный массив, в котором допустимы
такие ключи, как ‘filter’, ‘flags’, ‘options’;
- $add_empty – параметр, который в значении true добавляет отсутствующие
ключи со значением null.

Функция filter_input()
Функция filter_input(), в отличие от filter_var(), принимает переменную из
глобальных массивов поступающей информации $_GET, $_POST, $_COOKIE, $_SERVER,
$_ENV.
Синтаксис функции:
mixed filter_input(int $type, string $variable_name [, int $filter = FILTER_DEFAULT, mixed
$options])
Функция принимает следующие параметры:
- $type – тип поступающей информации, принимает одну из констант:
INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV;
- $variable_name – имя переменной, входящей в глобальный массив;
- $filter – тип используемого фильтра;
- $options – ассоциативный массив или логическое ИЛИ флагов.

4
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

Функция filter_ input_array()


Аналогично функции filter_input() функция принимает ассоциативный массив
переменных из одного из глобальных массивов.
Синтаксис функции:
mixed filter_input_array(int $type [, mixed $definition, bool $add_empty = true])
Функция принимает следующие параметры:
- $type – тип поступающей информации, принимает одну из констант:
INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV;
- $definition – ассоциативный массив, аналогичный по принципу построения
массиву из функции filter_var_array();
- $add_empty – параметр, который в значении true добавляет отсутствующие
ключи со значением null.

Функции обработки строковых переменных


Функция addslashes()
Функция экранирует строку с помощью слешей. Аналогична использования в
ранее рассмотренных функциях фильтрации фильтра
FILTER_SANITIZE_MAGIC_QUOTES.
Синтаксис функции:
string addslashes(string $str)
С помощью символа «\» экранируются такие символы, как:
- одинарная кавычка «’»;
- двойная кавычка «”»;
- обратный слеш «\»;
- NUL (байт null).
Функция htmlentities()
Функция преобразует все возможные символы в соответствующие HTML-
сущности
Синтаксис функции:
string htmlentities(string $string [, int $flags = ENT_COMPAT | ENT_HTML401, string
$encoding = ini_get(“default_charset”), bool $double_encode = true])
Функция преобразует все символы в соответствующие HTML-сущности.
Содержит следующие параметры:
- $string – строка для обработки;
- $flags – битовая маска из флагов, определяющих режим обработки кавычек,
некорректных кодовых последовательностей и используемый тип документа и
может принимать следующие константы:
- ENT_COMPAT - преобразует двойные кавычки, одинарные кавычки не
изменяются;
- ENT_QUOTES - преобразует как двойные, так и одинарные кавычки;
- ENT_NOQUOTES - оставляет без изменения как двойные, так и одинарные
кавычки;
- ENT_IGNORE - молча отбрасывает некорректные кодовые
последовательности вместо возврата пустой строки. Использование
этого флага не рекомендуется, так как это может внести уязвимости в
ваш код;
- ENT_SUBSTITUTE - заменяет некорректные кодовые последовательности
символом замены Юникода U+FFFD в случае использования UTF-8 и

5
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

&#FFFD при использовании другой кодировки, вместо возврата пустой


строки;
- ENT_DISALLOWED - заменяет неверные коды символов для заданного
типа документа символом замены юникода U+FFFD (UTF-8) или &#FFFD,
при использовании другой кодировки, вместо того, чтобы оставлять все
как есть. Это может быть полезно, например, для того, чтобы убедиться
в формальной правильности XML-документов со встроенным внешним
контентом;
- ENT_HTML401 - обработка кода в соответствии с HTML 4.01;
- ENT_XML1 - обработка кода в соответствии с XML 1;
- ENT_XHTML - обработка кода в соответствии с XHTML;
- ENT_HTML5 - обработка кода в соответствии с HTML 5.
- $encoding – необязательный параметр, определяющий кодировку,
используемую при конвертации символов. По умолчанию используется UTF-8.
- Если необходимо раскодировать строку из HTML-сущностей обратно,
необходимо использовать функцию html_entity_decode():
Синтаксис функции:
string html_entity_decode(string $string [, int $flags = ENT_COMPAT | ENT_HTML401,
string $encoding = ini_get(“default_charset”)])
Параметры функции аналогичны функции htmlentities().
Функция htmlspecialchars()
В отличие от htmlentities(), преобразует в HTML-сущности только специальные
символы.
string htmlspecialchars(string $string [, int $flags = ENT_COMPAT | ENT_HTML401, string
$encoding = ini_get(“default_charset”), bool $double_encode = true])
Список параметров функции аналогичен функции htmlentities().

Примеры работы функций фильтрации данных


В этой части урока Вы рассмотрите практический результат работы
рассмотренных ранее функций filter_var(), filter_var_array(), filter_input(),
filter_input_array(), addslashes(), htmlentities() и htmlspecialchars().
Функции filter_var() и filter_var_array():
Листинг 44.1. Примеры работы функций filter_var() и filter_var_array()

//Создаем переменные, которые будут переданы в качестве параметров для


фильтрации
//Переменные-аргументы для функции filter_var()
$validate = 'mfsd*#@mail<script>.com';
$sanitize = 'mfsd*#@mail<script>.com';
//Ассоциативный массивы переменных для функции filter_var_array()
$validate_array = array(
'choice' => 'Yes',
'domain' => 'example<>().abrakadabra.com',
'email' => 'mfsd*#@mail<script>.com',
'float' => '1233.23',
'int' => 'fdsfsd123',
'IP' => '1234.sdf.123.fds',
'URL' => 'example<>().abrakadabra.com'

6
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

);
$sanitize_array = array(
'email' => 'mfsd*#@mail<script>.com',
'URL' => 'example<>().abrakadabra.com',
'float' => '1233fr.23fd',
'int' => 'fdsfsd123',
'spec_chars' => '<script>$fdsfsdlk=$fkjld;<script>',
'string' => '<p>Abrakadabra</p>'
);

//Ассоциативные массивы параметров фильтрации для функции filter_var_array()


$validate_parameters = array(
'choice' => FILTER_VALIDATE_BOOLEAN,
'domain' => array(
'filter' => FILTER_VALIDATE_DOMAIN,
'flags' => FILTER_FLAG_HOSTNAME
),
'email' => FILTER_VALIDATE_EMAIL,
'float' => FILTER_VALIDATE_FLOAT,
'int' => array(
'filter' => FILTER_VALIDATE_INT,
'options' => array(
'min_range' => 0,
'max_range' => 10000
)
),
'IP' => array(
'filter' => FILTER_VALIDATE_IP,
'flags' => FILTER_FLAG_IPV4
),
'URL' =>FILTER_VALIDATE_URL
);
$sanitize_parameters = array(
'email' => FILTER_SANITIZE_EMAIL,
'URL' => FILTER_SANITIZE_URL,
'float' => FILTER_SANITIZE_NUMBER_FLOAT,
'int' => FILTER_SANITIZE_NUMBER_INT,
'spec_chars' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
'string' => FILTER_SANITIZE_STRING
);

//Функции фильтрации
//Функция filter_var()
$validate = filter_var($validate, FILTER_VALIDATE_EMAIL);
$sanitize = filter_var($sanitize, FILTER_SANITIZE_EMAIL);
//Функция filter_var_array()
$validate_array = filter_var_array($validate_array, $validate_parameters);

7
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

$sanitize_array = filter_var_array($sanitize_array, $sanitize_parameters);

//Вывод данных
//Аргументы-переменные
echo "<p><b>Результат работы функции проверки (валидации) аргумента-
переменной:</b> $validate</p>";
echo "<hr>";
echo "<p><b>Результат работы функции очистки аргумента-переменной:</b>
$sanitize</p>";
echo "<hr>";
//Ассоциативные массивы данных
echo "<b>Результат работы функции проверки ассоциативного массива аргументов-
переменных:</b>";
foreach($validate_array as $k => $v)
echo "<p>[{$k}] => $v</p>";
echo "<hr>";
echo "<b>Результат работы функции очистки ассоциативного массива аргументов-
переменных:</b>";
foreach($sanitize_array as $k => $v)
echo "<p>[{$k}] => $v</p>";
echo "<hr>";

Как видно из результатов работы листинга 49.1, в случае использования


фильтров проверки (в частности, без использования параметра default), некоторые
переменные после проверки оказались очищенными от изначальных значений,
тогда как при использовании фильтров очистки все параметры были обработаны и
возвращены.
Функции filter_input() и filter_input_array()
Листинг 44.2. Примеры работы функций filter_input() и filter_input_array()

if($_POST['submit']){
$input_var = filter_input(INPUT_POST, 'mail', FILTER_SANITIZE_EMAIL);
$def = array(
'name' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
'mail' => FILTER_SANITIZE_EMAIL,
'url' => FILTER_SANITIZE_URL
);
$input_array = filter_input_array(INPUT_POST, $def);
echo "<p><b>Результат фильтрации аргумента-переменной из массива
\$_POST:</b> $input_var</p>";
echo "<hr>";
echo "<b>Результат фильтрации данных, поступивших из массива \$_POST:</b>";
foreach($input_array as $k => $v)
echo "<p><i>[{$k}]</i>: {$v}</p>";
echo "<hr>";
} else {
echo "<form action=\"Listing_49.2.php\" method=\"post\">

8
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

<div>
<input type=\"text\" name=\"name\" placeholder=\"Имя пользователя\">
</div>
<div>
<input type=\"text\" name=\"mail\" placeholder=\"Email пользователя\">
</div>
<div>
<input type=\"text\" name=\"url\" placeholder=\"Адрес сайта\">
</div>
<div>
<input type=\"submit\" name=\"submit\" value=\"Отправить\">
</div>
</form>";
}

В результате работы листинга 44.2. Вы попадете на страницу формы, поля


которой будут использованы в функции фильтрации данных. После отправки
данных, они будут обработаны и выведены на экран. Результат работы функции
может быть следующим:
Вводные данные:
Логин: user7\*&#
Email: user&#()@sdf&#*.com
URL: user&#()@sdf&#*.com
Результат:
Результат фильтрации аргумента-переменной из массива $_POST:
user&#@sdf&#*.com
Результат фильтрации данных, поступивших из массива $_POST:
[name]: user7\*&#
[mail]: user&#@sdf&#*.com
[url]: www&*.user#$&.com
Как видно, из входных значений были удалены символы, которые не отвечают
пропускным требованиям параметров фильтрации.
Функции addslashes(), htmlentities(), html_entity_decode(), htmlspecialchars():
Листинг 44.3. Работа функций addslashes(), htmlentities(),
html_entity_decode(), htmlspecialchars()

//Объявляем переменны для обработки функциями


$string = "Держи нос по ветру, но не бросай слов на ветер. О'Генри";
$script_string = "<?php for(\$i=0;\$i<5;\$i++)echo\$i;?>";

//Выводим на экран результаты работы функций


echo "<p><b>Результат работы функции addslashes():</b> ".addslashes($string)."</p>";
echo "<p><b>Результат работы функции htmlentities():</b>
".htmlentities($script_string)."</p>";
echo "<p><b>Результат работы функции htmlspecialchars():</b>
".htmlspecialchars($script_string)."</p>";

Результатом работы функций будут следующие экранированные строки:

9
Лекции курса PHP7 + MySQL с нуля
(краткое содержание)

Результат работы функции addslashes(): Держи нос по ветру, но не бросай слов на


ветер. О\'Генри
Результат работы функции htmlentities(): <?php for($i=0;$i<5;$i++)echo$i;?>
Результат работы функции htmlspecialchars(): <?php for($i=0;$i<5;$i++)echo$i;?>

10