×
Закрытие
7
×

Дополнительные материалы бесплатно предоставляются только зарегистрированным пользователям.

Для скачивания исходных файлов необходимо авторизоваться под своим аккаунтом через соответствующую форму.

Для тех кто не зарегистрирован, можно это сделать на вкладке Регистрация.

Статья сборника Как установить графический редактор GIMP

Перейти к статье

Устанавливаем графический редактор GIMP

  1. Выбор графического редактора
  2. Устанавливаем программу GIMP
  3. Устанавливаем Руководство пользователя

Здравствуйте уважаемый посетитель!

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

В статье Устанавливаем бесплатный графический редактор GIMP речь пойдет о бесплатной программе GIMP, которая позволяет в полной мере решать вопросы по созданию элементов дизайна веб-страниц. И будет показано, как ее установить на локальный компьютер.

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

Для тех же, кто хочет заниматься дизайном на платном Adobe Photoshop (фотошоп), здесь также упомянут и такой вариант, основанный на использовании продления льготного бесплатного периода фотошопа на неопределенное время...

    Cайт на практическом примере

    Текущее состояние создаваемого сайта

    Здесь можно посмотреть текущее состояние сайта, создаваемого в рамках цикла статей Самописный сайт с нуля своими руками.

    Исходные файлы данного сайта можно скачать из прилагаемых к статьям дополнительных материалов.

    Вы здесь: Главная → Сборник статей → Формы → Получение и проверка данных из формы в PHP


    Автор: / Дата:

    Получаем и проверяем данные из формы в PHP

    Здравствуйте, уважаемый посетитель!

    В предыдущих статьях мы подготовили форму оформления заказа используя инструменты проверки корректности ввода данных на стороне клиента. Для этого сначала использовали встроенные возможности HTML5, а затем для проверки ввода пароля дополнительно создали скрипты JavaScript.

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

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

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

    В случае же если на сайте для проверки формы на стороне клиента применены специально созданные скрипты, то не трудно в браузере отключить JavaScript и вводить в поля все, что заблагорассудится. Включая различные теги и другие запрещенные комбинации символов, которые могут нанести серьезный вред работе сайта.

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

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

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

    Содержание


    • Получаем данные от элементов формы в PHP
    • Создаем универсальную функцию проверки и обработки данных формы
    • Выполняем валидацию формы на стороне сервера
    • Проверяем валидацию на практических примерах
    • Исходные файлы сайта

    Получаем данные от элементов формы в PHP


    Ранее при формировании формы мы использовали метод POST. Поэтому получить данные в PHP можно с помощью ассоциативного массива $_POST[], который содержит все значения, передаваемые из формы этим методом.

    При этом в качестве индекса массива должны применяться значения атрибута "name" соответствующих элементов . Например, для поля "Марка автомобиля" это будет "marka", для поля "Модель" - "model" и т.д.

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

    1. if (!empty($_POST["righting-button"])) {

    2. $marka = $_POST["marka"];

    3. $model = $_POST["model"];

    4. $year = $_POST["year"];

    5. $vin = $_POST["vin"];

    6. $insurance = $_POST["insurance"];

    7. $order = $_POST["order"];

    8. if ($order == "1") $namer_order = "Набор для самостоятельной маркировки";

    9. if ($order == "2") $namer_order = "Противоугонная маркировка специалистом в сервис-центре";

    10. if ($order == "3") $namer_order = "Маркировка с индивидуальным дизайном";

    11. $center_price = $_POST["center_price"];

    12. $discount_price = $_POST["discount_price"];

    13. $client_name = $_POST["client_name"];

    14. $client_email = $_POST["client_email"];

    15. $client_login = $_POST["client_login"];

    16. $client_password_1 = $_POST["client_password_1"];

    17. $client_password_2 = $_POST["client_password_2"];

    18. echo nl2br($marka. "\n" .$model. "\n" .$year."\n" .$vin. "\n" .$insurance. "\n" .$namer_order. "\n" .$center_price. "\n" .$discount_price. "\n" .$client_name. "\n" .$client_email. "\n" .$client_login. "\n" .$client_password_1. "\n" .$client_password_2);

    19. }

    20. ?>

    Рис.1 PHP-код для получения данных из формы

    Как было выше отмечено, данные из формы извлекаются из ассоциативного массива $_POST[] в виде соответствующих переменных (поз.3÷8, поз.12÷15 ). Причем это происходит в момент отправки формы при нажатии на кнопку "submit" при непустом ее значении !empty($_POST["righting-button"]) (поз.2).

    При этом можно обратить внимание на то, что для поля "Вид заказа" (name="order") получение данных в виде текста формируются исходя из цифровых значений атрибута "value" выделенных пунктов списка

    Обусловлено это тем, что атрибут "value" в этих элементах также используется и для получения соответствующих значений через созданный ранее JavaScript-скрипт. В котором значения "value" для упрощения определены порядковой последовательностью чисел от 1 до 3.

    Поэтому используя условный оператор if несложно полученную "1" в переменной $order преобразовать в текст "Набор для самостоятельной маркировки" переменной $namer_order (поз.9). При "2" - переменная $namer_order будет уже содержать "Противоугонная маркировка специалистом в сервис-центре" (поз.10). А при "3" - "Маркировка с индивидуальным дизайном" (поз.11).

    И далее при обработке данных будет использоваться не первоначальная переменная $order с цифровым значением, а новая переменная $namer_order с соответствующим сохраненным тестом.

    Кроме того в строке 16, дополнительно, для возможности проверки полученных данных здесь применена функция echo nl2br. С помощью которой соответствующие полям значения переменных можно временно вывести на страницу для сравнения их с введенными данными. Очевидно, что в рабочем состоянии данную строку следует закомментировать.

    На скриншоте видно, что выведенные на страницу данные из формы в PHP полностью соответствуют заполненным полям.

    Полученные данные из формы в PHP

    Рис.2 Отправка формы при неправильном вводе пароля

    После того, как мы получили данные, теперь можно перейти и к решению вопроса валидации.

    Создаем универсальную функцию проверки и обработки данных формы


    При валидации на стороне сервера в нашем варианте будут предусмотрены следующие проверки и преобразования данных, полученных из формы:

    • Определение пустых полей для элементов, которые обязательны для заполнения;
    • Удаления пробелов из начала и конца строки;
    • Удаление экранированных символов (данные возвращаются с вырезанными обратными слешами, например \' становится ' и т.п., а двойные обратные слеши \\ становятся одинарными \);
    • Удаление HTML и PHP тегов;
    • Преобразование специальных символов в HTML-сущности ('&' преобразуется в '&amρ;' и т.д.);
    • Проверка на соответствие данных заданному шаблону.

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

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

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

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

    Ниже показан вариант PHP-кода такой универсальной функции с именем "check_symbol", которая может быть использоваться для разных типов полей формы.

    1. //----Функция проверки и преобразования данных из формы----

    2. function check_symbol($value, $field_name, $required, $pattern){

    3. if ($required == "1" && empty($value)) {

    4. $GLOBALS['alert'] = $GLOBALS['alert'].'Поле \"'.$field_name.'\" не заполнено'.'\n';

    5. return ;

    6. }

    7. $value = trim($value);

    8. $value = stripslashes($value);

    9. $value = strip_tags($value);

    10. $value = htmlspecialchars($value);

    11. if ($pattern != "0") {

    12. if (!empty($value) && !preg_match($pattern, $value, $matches)) $GLOBALS['alert'] = $GLOBALS['alert'].'Значение в поле \"'.$field_name.'\" не соответствует шаблону'.'\n';

    13. }

    14. return $value;

    15. }

    16. ?>

    Рис.3 PHP-код универсальной функции валидации данных, полученных из формы

    Как видно, в данной функции определено четыре параметра (поз.3) с помощью которых осуществляется передача значений аргументов, а именно:

    • $value - проверяемые данные;
    • $field_name - наименование поля;
    • $required - флаг обязательного заполнения поля ("0" - не обязательно, "1" - обязательно);
    • $pattern - шаблон регулярного выражения (при "0" проверка на соответствие шаблону не производится).

    Сам PHP-код функции достаточно простой. В первую очередь с помощью условного оператора if производится проверка на заполнение поля (поз.4). И если при значении флага обязательного заполнения ($required) равного "1" поле окажется пустым (empty($value)), то в переменной глобальной области видимости $GLOBALS['alert'] добавится соответствующая запись с указанием имени поля ($field_name) (поз.5). После чего оператором return работа функции завершится (поз.6).

    Если же поле будет заполнено, то с помощью функций trim (поз.8), stripslashes (поз.9), strip_tags (поз.10) и htmlspecialchars (поз.11) поочередно будут выполнены вышеуказанные преобразования данных по удалению ненужных пробелов и символов.

    А затем при ненулевом значении шаблона с помощью функции preg_match выполняется проверка на соответствие регулярному выражению. И если заданный шаблон ($pattern) не соответствует значению поля ($value), то аналогичным образом в глобальной переменной $GLOBALS['alert'] об этом добавится запись (поз.13).

    Завершается же работа функции возвращением результата в виде переменной $value с сохраненными данными после выполнения всех преобразований (поз.15).

    И последнее на что стоит обратить внимание, это применение в данной функции глобальной переменной $GLOBALS, которая используется в виде ассоциативного массива $GLOBALS[]. По-существу она является суперглобальной, так как доступна в любом месте, будь это PHP-скрипт, функция или метод.

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

    Теперь, после того, как мы создали функцию, разместим ее код в отдельном файле с наименованием "functions.php", расположив его в отдельной папке, скажем под именем "php".

    А для того, чтобы можно было обращаться к созданной функции, с помощью инструкции "require_once" подключим этот файл, аналогично тому, как мы это делали ранее при подключении функций для работы с базой данных MySQL.

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

    1. require_once "mysql/connect.php";

    2. require_once "mysql/functions.php";

    3. require_once "php/functions.php";

    4. ?>

    Рис.4 Подключение созданной функции

    В итоге необходимая пользовательская функция создана и готова к использованию.

    Выполняем валидацию формы на стороне сервера


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

    В этом случае для проверки полей не нужно выполнять каких-либо отдельных преобразований, и соответственно, не потребуется значительного увеличения кода в ранее созданном скрипте, изображенном на рис.1. Так как для этого необходима будет всего лишь одна дополнительная строка для каждого поле.

    В следующей таблице показан дополненный PHP-код скрипта, в котором добавлены соответствующие строки для всех имеющихся полей формы онлайн заказа (добавленные строки обозначены светлым фоном).

    1. if (!empty($_POST["righting-button"])) {

    2. $marka = $_POST["marka"];

    3. $marka = check_symbol($marka, "Марка автомобиля", "1", "/^[ A-ZА-ЯЁ]+\z/iu");

    4. $model = $_POST["model"];

    5. $model = check_symbol($model, "Модель", "1", "/^[0-9A-ZА-ЯЁ]+\z/iu");

    6. $year = $_POST["year"];

    7. $year = check_symbol($year, "Год выпуска", "1", "/^[0-9]{4}\z/");

    8. $vin = $_POST["vin"];

    9. $vin = check_symbol($vin, "Последние 6 цифр VIN", "1", "/^[0-9]{6}\z/");

    10. $insurance = $_POST["insurance"];

    11. $insurance = check_symbol($insurance, "Страховая компания", "1", "/^[ 0-9A-ZА-ЯЁ-]+\z/iu");

    12. $order = $_POST["order"];

    13. if ($order == "1") $namer_order = "Набор для самостоятельной маркировки";

    14. if ($order == "2") $namer_order = "Противоугонная маркировка специалистом в сервис-центре";

    15. if ($order == "3") $namer_order = "Маркировка с индивидуальным дизайном";

    16. $namer_order = check_symbol($namer_order, "Вид заказа", "1", "/^[ А-ЯЁ-]+\z/iu");

    17. $center_price = $_POST["center-price"];

    18. $center_price = check_symbol($center_price, "Цена сервис-центра", "0", "/^[0-9]+р\.\z/");

    19. $discount_price = $_POST["discount-price"];

    20. $discount_price = check_symbol($discount_price, "Цена со скидкой", "0", "/^[0-9]+р\.\z/");

    21. $client_name = $_POST["client-name"];

    22. $client_name = check_symbol($client_name, "Имя", "1", "/^[А-ЯЁ]{3,}\z/iu");

    23. $client_email = $_POST["client-email"];

    24. $client_email = check_symbol($client_email, "E-mail", "0", "/^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,6}\z/i");

    25. $client_login = $_POST["client-login"];

    26. $client_login = check_symbol($client_login, "Логин", "1", "/^[0-9A-Z]{3,}\z/i");

    27. $client_password_1 = $_POST["client-password_1"];

    28. $client_password_1 = check_symbol($client_password_1, "Пароль", "1", "/^[0-9A-Z]{6,}\z/i");

    29. $client_password_2 = $_POST["client-password_2"];

    30. $client_password_2 = check_symbol($client_password_2, "Подтверждение пароля", "1", "/^[0-9A-Z]{6,}\z/i");

    31. if ($client_password_1 != $client_password_2) $GLOBALS['alert'] = $GLOBALS['alert'].'Значения в полях ввода пароля не совпадают';

    32. //echo nl2br($marka. "\n" .$model. "\n" .$year."\n".$vin. "\n" .$insurance. "\n" .$namer_order. "\n" .$center_price. "\n" .$discount_price. "\n" .$client_name. "\n" .$client_email. "\n" .$client_login. "\n" .$client_password_1. "\n" .$client_password_2);

    33. if (!empty($GLOBALS['alert'])) {

    34. $GLOBALS['alert'] = 'Данные из формы не отправлены. Обнаружены следующие ошибки: \n'.$GLOBALS['alert'];

    35. include "alert.php";

    36. }

    37. }

    38. ?>

    Рис.5 PHP-код получения и валидации данных из формы

    Здесь видно, что при вызове пользовательской функции "check_symbol" для каждого поля задаются определенные значения параметров.

    Например, для поля "Марка автомобиля" (поз.4) первый параметр имеет значения данных, полученных из этого поля в виде переменной $marka, второй - название самого поля, третий "1", означающее обязательное заполнение поля и четвертый - регулярное выражение "/^[ A-ZА-ЯЁ]+\z/iu", в котором предусмотрено использование только букв латинского и русского алфавита и пробелов.

    Для сравнения в поле "E-mail" (поз.25) первый параметр имеет значения данных в виде переменной $client_email, второй - название самого поля, третий "0", соответствующее необязательному заполнению поля и четвертый - регулярное выражение /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,6}\z/i", в котором определен шаблон допустимого написания адреса электронной почты.

    Что касается регулярных выражений, то это достаточно обширная тема, достойная отдельного серьезного рассмотрения. Ранее при преобразовании входящих ЧПУ с помощью модуля MOD_REWRITE мы уже касались этого вопроса и использовали большинство включенных в данный скрипт символов регулярных выражений.

    Поэтому не будем повторяться, дополнительно отметив лишь применение здесь модификаторов, таких как: "i" для игнорирования регистра, что позволяет указывать в шаблонах лишь только строчные или прописные буквы и "u", необходимый в данном случае для корректности проверки на соответствие букв на кириллице в кодировке UTF-8.

    Кроме того, в данном коде PHP для выделения шаблона используются символы специального разделителя "/" (можно также "|", "{", "!" и т.п ), а начало и конец строки обозначены символами "^" и "\z", соответственно.

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

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

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

    Поэтому она реализована отдельно (поз.32). Для этого используется условный оператор if в котором сравниваются значения переменных ($client_password_1) и ($client_password_2). И в случае их несоответствия, в глобальную переменную $GLOBALS['alert'] добавится соответствующая запись.

    Следует отметить, что после объявления в функции глобальной переменной $GLOBALS['alert'], в PHP-скрипте можно использовать ее и в виде обычной локальной переменной, соответствующей имени индекса массива. В данном случае это будет переменная $alert. Но мы так поступать не будем, преднамеренно обозначив, что это именно глобальная переменная, не путая ее с локальной.

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

    Для этого после проверок данных всех полей в нижней части скрипта с помощью условного оператора if оценивается состояние глобальной переменной $GLOBALS['alert'] (поз.34), в которую ранее записывались сообщения об ошибках.

    И если эта переменная не пустая, то к ее значению добавляется шапка сообщения с текстом "Данные из формы не отправлены. Обнаружены следующие ошибки:" (поз.35). А кроме этого вызывается некий файл "alert.php" (на данный момент такого файла не существует, его нужно создать).

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

    А для того, чтобы решить эту проблему мы перенесем данные о сообщении из PHP в JavaScript. Для этого создадим в корневом каталоге отдельный файл с именем "alert.php" и запишем в него следующий код:

    Рис.6 Формирование вывода сообщения в диалоговом окне браузера из переменной PHP

    Таким образом в случае ошибки при отправке формы данные из глобальной переменной PHP $GLOBALS['alert'] будут использоваться методом "alert" языка JavaScript в качестве параметра для отображения в диалоговом окне текст сообщения. И при неуспешной валидации данных отправляемой формы пользователь должен получить сообщение о возникшей проблеме с указанием допущенной ошибки.

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

    Проверяем валидацию на практических примерах


    Чтобы иметь возможность практически проверить, работает ли валидация данных из формы на стороне сервера, необходимо на время отключить ранее предусмотренные нами проверки на стороне клиента с использованием встроенных возможностей языка HTML5 и созданных скриптов JavaScript.

    Для этого нужно временно удалить в элементах формы все имеющиеся атрибуты "required", определяющие обязательность заполнения полей и "pattern", задающие шаблон соответствия регулярному выражению. А также удалить из тега

    атрибут события "onsubmit", указывающий вызываемую функцию валидации пароля.

    После всех этих мероприятий, проверим валидацию в трех вариантах отправки формы:

    • При всех незаполненных полях.
    • При заполненных полях с различными вариантами ошибок;
    • При всех правильно заполненных полях.

    При этом раскомментируем включенную в скрипт строку с функцией echo nl2br (поз.33, рис.5), предназначенную для временного отображения на странице полученных из формы данных.

    Первый вариант отправки формы при незаполненных полях показан на следующем скриншоте.

    Отправка формы при незаполненных полях

    Рис.7 Отправка формы при незаполненных полях

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

    При этом поля "Цена сервис-центра" и "Цена со скидкой" в этом списке отсутствуют, так как пользователями они не заполняются, а формируются автоматически исходя из выбранного вида заказа. А поле "E-mail заведомо необязательно для заполнения.

    Теперь заполним все поля, допустив в некоторых их них возможные ошибки, например:

    • использование недопустимых символов (в поле "Имя" кроме букв добавим цифру, а в поле "E-mail" заменим символ "@", к примеру, на "$" ;
    • использование недопустимого количества символов (в поле "Логин" укажем всего два символа вместо трех и более;
    • ошибочное повторение пароля.
    Отправка формы при неправильно заполненных полях

    Рис.8 Отправка формы при неправильно заполненных полях

    Как видно этот тест тоже пошел успешно.

    Ну а теперь проверим последний вариант - отправим форму со всеми правильно заполненными полями.

    Отправка формы при правильно заполненных полях

    Рис.8 Отправка формы при правильно заполненных полях

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


    Таким образом мы получили все данные из формы и успешно провели тесты на проверку валидации. И теперь можно перейти непосредственно к отправке формы. Что мы и сделаем в следующей статье.

    Исходные файлы сайта


    Знак папкиИсходные файлы сайта с обновлениями, которые были сделаны в данной статье, можно скачать из прилагаемых дополнительных материалов:

    • Файлы каталога www
    • Таблицы базы данных MySQL

    Дополнительные материалы бесплатно предоставляются только зарегистрированным пользователям.

    Для скачивания исходных файлов необходимо авторизоваться под своим аккаунтом через соответствующую форму.

    Для тех кто не зарегистрирован, можно это сделать на вкладке Регистрация.

    С уважением,


    Комментарии


    Если у Вас возникли вопросы, или есть какие-либо пожелания по представлению материала, либо заметили какие-нибудь ошибки, а быть может просто хотите выразить свое мнение, пожалуйста, оставьте свои комментарии. Такая обратная связь очень важна для возможности учета мнения посетителей.

    Буду Вам за это очень признателен!