Формы, часть 2, “Проверка формы на PHP”

« Предыдущая запись
 
  Следующая запись »
 

formform Формы, часть 2, “Проверка формы на PHP” Доброго всем вечера (скорее ночи – прим.ред.). Сегодня мы будем немного совершенствовать ту форму, которую сделали в предыдущем посте. Для начала научимся делать проверку формы на php и сделаем некоторые манипуляции по защите.

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

  1. Изменено название полей формы. Вы спросите – на кой хрен нам это надо? А всё просто, отвечу я вам. Насколько мне известно, то некоторые спам боты рыскают по сайтам в поисках форм, и заполняют их, ориентируясь на названия этих полей. По идее если они не находят совпадений, то уходят восвояси, чего нам и надо. Конечно степень этой защиты не думаю, что особо велик, но от нас не убудет, а если писем спама уменьшится на 1 письмо, это уже будет хорошо=).
  2. Все переданные переменные получают свои имена с одновременной защитой от XSS-атак. Строки 9-11. Идёт совместное применение двух функций. Первая, stripslashes, раскавычивает строку, закавыченную функцией addslashes(). Те кто в танке, поясняю. По умолчанию, обычно, все кавычки слэшируются, то есть экранируются – то есть изначально была кавычка ‘, а специальной директировой она записалась как \’. А зачем нам убирать эти экраны? Всё дело в функции htmlspecialchars, которую мы применяем далее. Она берёт и всякие символы, например > и <, превращает в специальные сочетания &lt; и &rt;. Если бы мы оставили экраны, они бы тоже были переведены в такие символы и уже никуда бы из текста не делись, а это нам не нужно. Но может ещё остался вопрос – нам на кой вообще всё это? А вот представьте, что злоумышленник написал в какое-то поле нашей формы паразитный javascript код. Отправляя его через форму, он может быть обработан, и в итоге злоумышленник может чем-то вам навредить. Это и есть XSS-атака. Функция htmlspecialchars помогает этого избежать, заменив все открывающие и закрывающие теги кода, предотвратив тем самым атаку.
  3. Проверка поля на заполнение. Здесь (13 строка) добавляется оператор if, который проверяет заполненность поля почты. Если он окажется пустым, то выведется ошибка.
  4. Проверка на правильность ввода адреса почты. В 17 строке используется оператор elseif, который будет проверяться, если if вернул нам положительный ответ, то есть сказал, что  адрес почты вообще отсутствует, то есть не был введён. Здесь мы используем функцию preg_match, которая позволяет сравнить введённый адрес с регулярным выражением. Про регулярные выражения возможно я напишу кратко потом, а пока стоит знать, что регулярное выражение создаёт некий шаблон, с которым сверяется наша строка. И если, в нашем случае, введённый адрес не совпадает с выражением, то опять же будет выведена ошибка. Для примера вот ещё парочку регулярных выражений:
    |^[-а-яе\s\.,;:\?!]+$|i – это регулярное выражение позволяет использовать только русский алфавит и некоторые символы типа пробела, точки, запятой и пр.
    #http://[-a-z0-9_.]+[-a-z0-9_:@&?=+,.!/~*’%$]*\.(html?|php)#i – а это выражение позволяет проверить правильность написание адреса в интернете.

 

Далее используется оператор else, куда уже перенесён весь наш код по отправке письма. Правила проверки можно создать самому в любом количестве, просто дописывайте новые elseif, как например для проверки адреса почты, и будет вам счастье.

<?
$mailto = "vashe_milo@mail.ru";
$charset = "windows-1251";
$subject = "Имя письма";
$content = "text/html";
$status="<br>";
if (!empty($_POST))
{
   $name = htmlspecialchars(stripslashes($_POST['imko']));
   $message = htmlspecialchars(stripslashes($_POST['tikstik']));
   $mail = htmlspecialchars(stripslashes($_POST['posta']));
  
   if(empty($_POST['posta']))
   {
      $status = "Вы не указали свой E-mail!";
   }
   elseif (!preg_match("/^[0-9a-z_\.]+@[0-9a-z_^\.]+\.[a-z]{2,6}$/i", $mail))
   {
      $status = "Вы ввели некорректный E-mail!";
   }
   else
   {
       $headers  = "MIME-Version: 1.0\r\n";
       $headers .= "Content-Type: ".$content." charset=".$charset."\r\n";
       $headers .= "From: \"".$name."\" <".$mail.">\r\n";
       $headers .= "Bcc: vashe_milo2@yaya.ru\r\n";
       $headers .= "X-Mailer: E-mail from my super-site \r\n";
       $sendmessage = "<html><body>
         <p><b>E-mail для связи:</b> ".$mail."</p>
         <p><b>Сообщение:</b> ".$message."</p>
         </body></html>";
       if (mail($mailto,$subject,$sendmessage,$headers))
       {
          unset($name, $mail, $message);
          $status = "Ваше сообщение отправлено!";
       }
       else
       {
          $status = "По техническим причинам сообщение не было отправлено. Попробуйте снова, а если не получится, обратитесь к разработчикам";
       }
   }
}
?>
<form method='post' name='formname'> 
    <p>
       <label for="imko">Контактное лицо:</label><br>
       <input name="imko" maxlength="50" type="text" size="10">
    </p>
    <p>
       <label for="posta">Почта для связи:</label><br>
       <input name="posta" type="text" size="10" value="">
    </p>
    <p>
       <label for="tikstik">Сообщение:</label><br>
       <textarea rows="5" cols="14" name="tikstik"></textarea>
    </p>
    <p>
       <input name="submit" type="submit" value="Отправить">
    </p>
</form>
<?=$status;?>

 

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

З.Ы.: а архив с примером можно скачать по ссылке

 

 

 

Ссылки по теме

, ,

1 звезда2 звезд3 звезд4 звезд5 звезд (голосов: 7, средний: 4.29 из 5)
Понравилась статья или журнал? Подписывайся на продолжение!
Отзывов: 48 на запись

"Формы, часть 2, “Проверка формы на PHP”"

  1. Не подскажешь как встваить данный код в свою страничку на html?
    Заранее благодарен.

  2. качай архив и встраивай его в свой код. только твой файл должен быть с расширением php

  3. Спасибо за ответ, я уже прикрутил.
    Как думаешь если сайт на ютф а почта на вин стоит, так можно ведь?

  4. почтовые клиенты и почтовые интерфейсы, как правило, работают с другими кодировками, так что можно

  5. почта не отправляется! при этом уверенно пишет что:
    “Ваше сообщение отправлено!”
    ваша форма не рабочая чтоль?? неясно где трабл…

  6. если не отправляется, это не значит, что скрипт не рабочий (не говоря уже о том, что его работа проверена).
    дай архив со своим примером, посмотрю

  7. Кирилл
    03/07/2010 at 13:00 Постоянная ссылка Цитировать

    На счет регулярного выражения: а если, например, почтовый сервер находится в домене .net.ru? Ведь тогда почтовый адрес не пройдет проверку, не так ли?

  8. пройдёт, так как после собаки в первом перечислении есть точка. то есть даже @abc.com1.net.ru пройдёт

  9. Кирилл
    07/07/2010 at 12:57 Постоянная ссылка Цитировать

    Ах, да, прошу прощения – сразу не заметил :)

  10. no problem =)

  11. Максим
    09/07/2010 at 12:55 Постоянная ссылка Цитировать

    Спасибо!!! Все работает.

  12. Пожалуйста

  13. Александр
    11/11/2010 at 17:40 Постоянная ссылка Цитировать

    Ну, код, конечно не сказать чтобы уж совсем “радость хакера”, но…
    две уязвимости просто лежат на поверхности. :)
    вот здесь первая:
    $name = htmlspecialchars(stripslashes($_POST['imko']))
    .. если интересно дальше – пишите :)

  14. всегда рад выслушать, чего уж там. может быть откроете мне правду на что-нибудь =)
    а на тему xss я писал отдельно. здесь не запаривался, для галочки пару тем впихнул
    http://shublog.ru/php/kak-zashhititsya-ot-xss-ataki-i-ustranit-uyazvimost/

  15. скажите пожалуйста а как защитить форму от подмены данных отправленных извне ?
    к примеру на сайте собирается инфа какая то и скрытыми полями в форме находится…а злоумышленник копирует форму меняет скрытые поля и … как защититься ? подскажите пожалуйста !

  16. Прежде всего советовал бы почитать статьи… Так, я думал я писал статью о SQL-инъекциях. Постараюсь исправить. Однако для ознакомления советую также прочитать http://shublog.ru/php/kak-zashhititsya-ot-xss-ataki-i-ustranit-uyazvimost/ и http://shublog.ru/php/pochemu-opasno-vklyuchat-parametr-php-register_globals/
    Они отдалённо затрагивают вопрос, в частности и о sql-инъекциях, что-то можно подчерпнуть оттуда.
    Мне думается, что прежде всего надо защитить скрипт на php уровне – т.е. максимальное число проверок на поля формы сделать. Тогда даже если со стороны будут обращаться к скрипту, они ничего не смогут сделать.
    Скрытые поля с какими-то данными лучше не использовать, если они несут информацию типа номера сессии, ид пользователя или ещё чего. Если форма использует данные авторизации, то тогда лучше передавать значения на уровне сессии.
    Есть ещё вариант, когда исполняемый скрипт, также как и форма, подключаются в какой-то каркас сайта, основная страница со всеми данными. Тогда в основной странице объявляется переменная, а в подключаемых файлах (в частности скрипта обработки формы) проверяется её наличие и значение, а далее идёт запуск обработки формы или прерывание сценария. И плюс в том, что злоумышленник не сможет узнать имя переменной и значение, если только не взломает фтп.

  17. Александр
    17/02/2011 at 15:17 Постоянная ссылка Цитировать

    “скажите пожалуйста а как защитить форму от подмены данных отправленных извне ?”
    Пока только тестом Тьюринга. То есть – “капчей”.
    Различить на backend’е, “вручную” ли пришел запрос (POST или GET) или от робота – принципиально невозможно. Собственно говоря, запрос приходит всегда “от робота” :) ))

    Есть более-менее простой способ, несколько ограждающий от роботов, но он все же от ленивых хакеров.
    Итак: отправка формы делается через AJAX с некоторыми вставками переменных “на лету”. Причем вставками не очень тривиально вычисляемыми. Да, дотошный хакер разберет код и поймет, но это время, это _отдельное_ внимание к вашему сайту. Оно хакеру надо? Есть куча сайтов, которые написаны по одному шаблону , так что…

  18. Извиняюсь за глупый вопрос, но не могу понять что делает последняя строчка?

  19. Тоже самое, что и
    <?php echo $status;?>

  20. Володя
    13/06/2011 at 21:55 Постоянная ссылка Цитировать

    Я в форму добавил скрытое поле. Оно пустое. При проверке надобно его проверить. Пользователь его не видит и заполнить не может, но если оно не пустое – значит спам-машина. Тока куда и как в ентот скрипт воткнуть – ума не приложу. Чайник я.

  21. Володя
    13/06/2011 at 22:11 Постоянная ссылка Цитировать

    при попытке отправить файл с письмом выдаёт ошибку: Warning: copy(сдесь он пишет имя_файла который отправлялся) [function.copy]: failed to open stream: Permission denied in /home/vov/i/k/k/ikking/public_html/svyaz.php on line 206
    В чём проблема?

  22. Володя
    13/06/2011 at 22:22 Постоянная ссылка Цитировать

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

  23. Володя
    14/06/2011 at 20:39 Постоянная ссылка Цитировать

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

  24. есть желание заказать такую форму для сайта (с капчей) сколько стоит?

  25. доброе утро! отписался вам на емейл

  26. Здравствуйте! Спасибо за статью!
    Из всего, что я читала про почту на PHP она – самая толковая.
    Все работает, но…
    Яндекс пишет все время :
    “ПРЕДУПРЕЖДЕНИЕ: плохие заголовки…” И т.д. При этом сами сообщения (когда их откроешь) выглядят нормально.
    Я не программист, (скорее – дизайнер-непрофессионал), и я понимаю, что дело тут в кодировках. НО:
    - весь сайт у меня написан в windows-1251, если на страничке бланка почты меняю кодировку на utf-8 то и текст письма становится нечитабелен.

    - К файлам настройки PHP у меня доступа нет.

    - Где бы я кодировки ни меняла /я успешно разделила php и html файлы/, все равно в почтовике лезут кракозябры. /можно, конечно, с ними жить, но – НЕРВИРУЕТ/

    Наши Хспециалисты плечами пожимают, типа: “Мы с этим не сталкивались”.
    А я сама – закоренелый гуманитарий.

    Так что, только на Вас вся надёжа. Заранее спасибо.

  27. Александр Шуйский
    06/04/2012 at 23:48 Постоянная ссылка Цитировать

    Вечер добрый!
    Кодировка исправляется в трёх местах. 1 – это теги meta в шапке страницы html. 2 – это непосредственно в заголовках создаваемого письма. 3 – это кодировка непосредственно файла скрипта. С первыми двумя думаю ясно где менять, а третье меняется при открытие файла в нормальном текстовом редакторе, поддерживающим кодировки. Там нужно задать кодировку не utf-8, а ansi (это в случае если везде нужны вин 1251)

  28. “2 – это непосредственно в заголовках создаваемого письма.” это в 3-ей и 25-ой строке примера?

    “в нормальном текстовом редакторе” – Notepad++ Нормальный?

    “(это в случае если везде нужны вин 1251)” Кабы я знала, какие и где мне нужны…

    Задумка была такая:
    Пользователь оформляет заявку (через форму),
    Инфа попадает в почту на яндексе
    Я копирую ФИО и т.д. со списка почты и РАДУЮСЬ.

    С последним пунктом пока не очень…

  29. Александр
    09/04/2012 at 20:07 Постоянная ссылка Цитировать

    в имени: ($_POST['imko'])
    vasya\r\nBcc: kto-ugodno@ms.com

  30. Александр
    09/04/2012 at 20:09 Постоянная ссылка Цитировать

    таким образом мы можем отослать копию письма на любой адрес.
    можно сделать проверку на переводы строк в имени.

  31. Александр Шуйский
    10/04/2012 at 10:50 Постоянная ссылка Цитировать

    1) да
    2) нормальный
    3) если всё на виндовс 1251, то она и нужна, везде

    кодировка файла меняется в текстовом редакторе – поищите в меню пункт Кодировка и название ANSI

  32. Наверно, дело не в кодировке. И ЭТО не кракозябры. Потому что получается письмо с адресом из цифр и слешей, с текстом:
    “WARNING: bad headers – Non-encoded 8-bit data (char C8 hex): Subject:
    \310\354\377 \357\350\361\374\354\340\n Improper use of control character
    (char 0D hex): MIME-Version: 1.0\r\n Improper use of control character (char
    0D hex): Content-Type: text/html charset=utf-8\r\n Improper use of control
    character (char 0D hex): From: “\314\340\352\361\350\354\356\342\340
    \305\352\340\362\345\360\350\355\340″ \r\n Improper use of control
    character (char 0D hex): X-Mailer: E-mail from my super-site \r\n”

    И вложенным файлом где адрес, имя, текст отправленного сообщения.

    / А кодировку я везде поменяла :) /

  33. Александр Шуйский
    10/04/2012 at 13:24 Постоянная ссылка Цитировать

    Присылайте файлы на почту, посмотрю что там

  34. неработаеттвояхрень
    07/05/2012 at 19:58 Постоянная ссылка Цитировать

    не работает твоя хорма.такие корки мочит)))

  35. Александр Шуйский
    07/05/2012 at 22:44 Постоянная ссылка Цитировать

    У всех работает, а у тебя не работает. Давай показывай чего там у тебя)

  36. Здравствуйте, Александр! Начитавшись за лето умных книг(благо оно было дождливым), я решилась написать
    свой первый php код (собраный из кусочков чужих примеров, но все же…)
    Это тест-игра где – вопрос и несколько варианта ответов, надо выбрать правильный,
    (radio-кнопка). Переключать-то он переключает, НО ссылается на последний вариант массива $_POST.
    Я понимаю, что мне его надо обнулить после прохождения, но КАК это сделать ума не приложу…
    ПЫ.СЫ.:
    У меня вопрос по поводу кавычек в форме: где и какие ставить? (Я ставила “”, но в книге
    Котерова и Костарева написано, что, мол, не везде оно надо и вредно для PHP…)
    ПЫ.ПЫ.СЫ.:
    Как сделать так, чтобы ключам в форме присваивалось значения массива ссылок?
    С помощью foreach? Или я вообще не в ту сторону смотрю?
    Спасибо.

    ///////// PHP-код /////////////////////////////////////////////////////
    // Переменные с сылками для ответов
    $mr_three=header(‘Location:http://путь к неправильному ответу’); //неправильный ответ
    $bon_boy1=header(‘Location:http://путь к правильному ответу 1′); // ко 2-ому вопросу
    $bon_boy2=header(‘Location:http://путь к правильному ответу 2′); // к 3-ему вопросу

    $logpos = $_POST['gemXb'];
    if($_POST['gemXb']===”ncorv”) {$logpos=$mr_three;}
    if ($_POST['gemXb']===”corv1″) {$logpos=$bon_boy1;}
    if ($_POST['gemXb']===”corv2″) {$logpos=$bon_boy2;}
    echo $logpos;

    //Кусок кода html-документа. Он у меня идет отдельно от скрипта
    ПЕРВАЯ

    Текст вопроса МНОГАБУКВ

    Вариант 1

    Вариант 2

    Вариант 3

    Вариант 4

  37. Александр Шуйский
    01/10/2012 at 9:05 Постоянная ссылка Цитировать

    Доброе утро!
    Обнуление можно делать при помощи функции unset.
    По поводу кавычек – если в тексте нет никаких переменных и “буквенных” переносов строк, то стоит использовать одинарные кавычки. В противном случае код немного утяжеляется, т.к. он в парных кавычках ищет переменные для интерпретации, а в одинарных сразу воспринимает как текст.
    По поводу последнего вопроса не очень понял о чём речь, и код не очень понял, что наворочено. Лучше напиши мне на почту с примером полного кода, посмотрю =)

  38. “Наворотить” – это я умею. )) Я сейчас захожу с другого боку.) Пока еще ОЧЕНЬ СТЫДНО что-то кому-то показывать. // Я всё думала: как же мне это (см. выше) стереть. // Читаю мануал (про массивы) оччень вдохновляет! Стихи (см. ниже) уже написала. С кодом (ну, чтоб (хотя бы) работал) сложнее))

    Итак:
    Из цикла “Издевательство над классикой” (Автор – я)

    Нас все учили понемногу:
    Чему-нибудь и как-нибудь…
    Уменьем кодерства, ей Богу,
    Сейчас немудрено блеснуть:
    Потолковать о мануале,
    В конце input поставить value
    И помнить, хоть не без греха,
    Из Стива Джобса 3 стиха.

  39. Александр Шуйский
    02/10/2012 at 8:18 Постоянная ссылка Цитировать

    Хах, ну смотрите, если передумаете – присылайте =)
    Отличный стих!

  40. Александр!
    У меня всё заработало!)) / Я тут просто РАДОСТЬЮ делюсь/

    НО! У меня вопрос: безопасно ли в action писать (“/имя_скрипта.php”), а не ? Потому что я никак не могу понять, КАК влепить
    слеш во втором случае. Ну то есть чтобы “братья” читали именно “/имя_скрипта.php”(со слешем) , потому что так: (action=”") им ничего “не видно”.
    Или это вообще не так делается? (у меня форма от скрипта отделена. Хостинг бесплатный. И пути, видать, кривые…)

    И (заранее предупреждаю, вопрос ИДИОТСКИЙ): можно ли объединять результаты функции в массив? например:

    $machexa=array()
    $n['v']=header(“поди туда, не знаю куда”);
    $n['v2']=header(“принеси то, не знаю что”);

    А потом еще использовать их в foreach и сессиях?…
    Если ответите – спасибо.)

  41. В пропусках – про глобальные переменные. Здесь они не печатаются ) :)

  42. Александр Шуйский
    12/10/2012 at 17:37 Постоянная ссылка Цитировать

    По правде я из всего этого сумбура ничего не понял =))))

  43. Здравствуйте еще раз!)
    Теперь пустые сообщения не приходят!
    Осталось пару нюансов:
    Как сделать, что бы после отправки сообщения открывалась отдельная страница с благодарностью за отправленное письмо?
    И открывались отдельно подготовленные странички с сообщениями о не првильно заполненным полем е-майл…

  44. Александр Шуйский
    27/05/2013 at 11:04 Постоянная ссылка Цитировать

    Для перехода на отдельную страницу используйте редирект там, где задаётся в переменную тот или иной статус.
    header("Location: http://site.com/pagename.html");

  45. Владислав
    14/07/2013 at 3:24 Постоянная ссылка Цитировать

    Благодаря вашим статьям сдвинулся с мёртвой точки! Правда пришлось добавить дефис(-) в проверку адреса для отправки сообщения. Спасибо, что делитесь своими знаниями доходчивым языком!

  46. Александр Шуйский
    14/07/2013 at 9:48 Постоянная ссылка Цитировать

    Большое спасибо за тёплые слова =)

  47. Александр, добрый день! Скачал шаблон джумлы установил на сайт! Сначала форма обратной связи не работала, перерыл кучу информации в интернете нашел форму которая работает и даже с защитой от спам ботов (скрытое поле). Но спам все равно приходит, похоже от людей. В сообщении на английском языке обычно указана ссылка на какой нибудь сайт и текст типа “заходи на мой сайт”.
    Вопрос: как запретить ссылки в тексте сообщения?

  48. Александр Шуйский
    28/11/2016 at 17:10 Постоянная ссылка Цитировать

    Алексей, здравствуйте!
    Самый лучший совет, который я могу тут дать – удалите джумлу и сделайте сайт на чём-нибудь другом)))

Добро пожаловать, коллега! Вы можете оставить свой отзыв:





Допустимые XHTML-теги:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Подписка на комментарии