PHP форма обратной связи с отправкой на email

Вы когда-нибудь хотели установить на свой сайт форму обратной связи? Наверняка Вы встречались с подобными скриптами. Как ни странно, готовые скрипты отправки формы на email пользуются большой популярностью (Вы можете убедиться в этом в любом архиве скриптов), причем их существует великое множество. Есть простые, в которых ничего не меняется, а есть сложные и большие системы, которые функционируют на mysql, позволяют динамически изменять любые поля, содержат кучу настроек... Но так ли они нужны? На мой взгляд необходимость в подобных системах очень сомнительна.

Тестировать отправку почты на домашнем компьютере не получиться. Для этого Вам необходим хостинг с поддержкой php и функциями отправки почты. Я рекомендую Вам хостинг-провайдера runweb.ru. Этот провайдер предлагает отличные тарифы, высочайшую скорость доступа и отличное обслуживание.

Методы отправки почты

Отправлять почту с сервера с помощью php можно двумя основными способами.
Я хочу рассмотреть оба этих способа по порядку.

Первый и самый простой - это использование php функции mail(). Функция очень простая и понятная, хотя отправка почты с использованием mail() имеет и ряд недостатков. Самый главный - письмо отправляется не напрямую, а через php. Одновременно программа php подставляет в письмо некоторые свои поля. Например, у Вас не получится корректно указать отправителя. В поле "from" (то есть от кого пришло письмо) в большинстве случаев будет стоять имя сервера. Все дело в том, что php подставляет свои заголовки в служебную строку письмо "from".

Тем не менее отправка почты с помощью функции mail() остается самым простым
способом отправить письмо с сервера. Давайте рассмотрим этот способ подробнее.

Функция mail() имеет следующий синтаксис:

mail($to, $subject, $body, $headers);
$to - это адрес получателя. Например, "ivan@ivanov.com".
$subject - тема письма. Например, "Вам пришло письмо".
$body - текст сообщения.
$headers - любые заголовки письма. Например, адрес отправителя будет выглядеть так: "from: dmitry@webtalk.ru".

Вот полный пример отправки почты с помощью mail():

mail("vash_email@domain.ru", "Тема письма", "Здравствуйте!nВам пришло письмо.", "from: site_name");

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

Теперь давайте посмотрим, как можно отправить письмо с помощью sendmail.

sendmail - это стандартная программа операционной системы unix, которая отправляет почту.
php может запускать unix-программы путем использования средства pipes (дословно "трубопроводы"). Это средство unix позволяет направлять данные из одной программы в другую, наподобие того, как мы пишем в файл. Только файлом в этом случае выступает программа (в частности, sendmail), которая и получает данные.

sendmail программа имеет множество параметров, мы будем использовать некоторые из них. Чтобы использовать sendmail, нужно открыть к нему поток (pipe). В php это делается использованием команды popen(), которая по синтаксису идентична команде fopen(). Путем использования popen() мы открывает поток к sendmail
для записи в него (помните, параметр режима "w"?), после чего можно отправлять в него данные обычной командой fputs(). Посмотрим, как полностью выглядит процедура отправки письма через sendmail:

<?
// описываем переменные и rfc заголовки письма
$from = "dmitry@webtalk.ru";
$recipients = "mail@domain.ru";
$headers = "content-type: text/plain; charset='windows-1251'";

// открываем sendmail и отправляем письмо
$mail = popen("/usr/sbin/sendmail -i -f$from -- $recipients", 'w');
$text_headers = "from: $fromnsubject: $subject".$headers;
fputs($mail, $text_headers);
fputs($mail, "n");
fputs($mail, $body);

// проверяем на ошибку
$result = pclose($mail) >> 8 & 0xff;
if ($result) echo "sendmail error! error code: $result";
?>

В этой программе первое, что мы делаем - описываем rfc заголовки. rfc - это службные поля, которые содержат всю информацию о письме. Увидеть пример rfc Вы можете, например, в программе the bat!, щелкнув правой кнопкой мыши на тексте письмо и выбрав "rfc-822 headers" (название пункта может отличаться). Чтобы убрать их, повторите действия. В заголовке мы описываем поля "content-type", которые указывают что письмо текстовое и в кодировке windows-1251 (стандартная кодировка windows). В качестве кодировки также может быть использовано "koi8-r", это стандартная кодировка unix. В этой статье мы не будем рассматривать возможные rfc заголовки подробно. Мы сделаем это чуть позже,
когда будем ближе работать с почтой. Итак, после того, как мы описали служебные переменные и заголовки письма, мы открываем sendmail. Обратите внимание на путь к программе "/usr/sbin/sendmail". На разных серверах он может отличаться!
Если эта строка не работает, спросите у Вашего провайдера, где расположен sendmail. Далее указываются параметры: "-i -f$from -- $recipients". Это стандартные параметры для отправки письма и в них подставляется два поля: $from - от кого, $recipients - адреса получателей. В нашем случае переменная $recipients содержит всего один адрес. На самом деле можно использовать несколько адресов, указывая их через пробел:

$recipients = "mail@domain.ru mail-1@domain.ru mail-2@domain.ru";

Далее мы записываем в поток сначала заголовки письма (переменная $text_headers), потом отделяем их символом переноса строки и записываем текст сообщения. Последний шаг - закрытие потока и проверка на ошибку. При правильном выполеннии в переменную $result помещается ноль, а если возникла ошибка, в нее записывается номер ошибки.

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

Создаем форму обратной связи

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

contact.php:

<!doctype html public "-//w3c//dtd html 4.01 transitional//en">

<html>
<head>
<title>Обратная связь</title>
</head>

<body>

<?

function show_form($s="") {
if ($s) echo "<b>Ошибка:</b> $s";
?>
<table width=450 cellpadding=0 cellspacing=1 bgcolor=#808080>
<form action="" method="post">
<tr><td colspan=2 bgcolor=#eaebef height=25 align=center>
<b>Прямая связь</b></td></tr>
<tr bgcolor=#f0f0f0>
<td height=30 width=200> <b>Ваше имя: *</b></td>
<td bgcolor=#ffffff> <input type=text name=name size=30></td>
</tr>
<tr bgcolor=#f0f0f0>
<td height=30> <b>Ваш email: *</b></td>
<td bgcolor=#ffffff> <input type=text name=email size=30></td>
</tr>
<tr bgcolor=#f0f0f0>
<td height=30> <b>Ваш сайт:</b></td>
<td bgcolor=#ffffff> <input type=text name=domain size=30></td>
</tr>
<tr bgcolor=#f0f0f0>
<td height=30 colspan=2>
<table width=100% cellpadding=5 cellspacing=5><tr><td>
<b>Ваше сообщение: *</b><br>
<textarea cols=50 rows=5 name=message></textarea>
</td></tr></table>
</td>
</tr>
<tr><td colspan=2 bgcolor=#eaebef height=35 align=center>
<input type="submit" value="Отправить вопрос"></td></tr>
<input type=hidden name=a value=1>
</form>
</table>
<p>
Поля, отмеченные звездочкой (*) должны быть заполнены.
<? 
exit();
};


// если не было добавления сообщения, выводим форму
if (!$_POST['a']) show_form();

// проверяем данные формы
if (!$_POST['name']) show_form("Укажите Ваше имя!");
if (!$_POST['email']) show_form("Укажите Ваш email!");
if (!$_POST['message']) show_form("Вы не заполнили текст сообщения!");

// описываем переменные и rfc заголовки письма

// обратный адрес будет указанным адресом отправителя сообщения
$from = $_POST['email']; 
$recipients = "admin@webtalk.ru"; // Ваш email
$subject="Тема письма";
$body=$_POST['message'];
$headers = "content-type: text/plain; charset='windows-1251'"; // кодировка письма

if(strpos($_SERVER['SERVER_SOFTWARE'], '(Win32)')===FALSE)
{
	// открываем sendmail и отправляем письмо
	$mail = popen("/usr/sbin/sendmail -i -f$from -- $recipients", 'w');
	$text_headers = "from: $fromnsubject: $subject".$headers;
	fputs($mail, $text_headers);
	fputs($mail, "n");
	fputs($mail, $body);

	// проверяем на ошибку
	$result = pclose($mail) >> 8 & 0xff;
}
else $result=(mail($recipients, $subject, $body, "from: ".$from."rn".$headers) ? FALSE : TRUE);


if ($result) echo "Сообщение не было отправлено!";
else echo "Спасибо, Ваше сообщение отправлено. Администратор свяжется с Вами в ближайшее время!";
?>

</body>
</html>

Теперь давате рассмотрим, как работает эта программа. Выполнение начинается со строки "if (!$a) show_form();", так как до этого указана функция, которая, естественно, не выполняется. В этой строке мы проверяем, была ли попытка заполнения формы (из формы, как Вы видите, передается переменная $a, которая и проверяется в этой строке). Если такой попытки не было, вызывается функция show_form(), которая выводит форму.

Далее, если форма уже передавалась скрипту, проверяются обязательные поля. Поля "имя", "email" и "текст сообщения" являются обязательными. Если какое-либо из них не заполнено, форма вызывается с параметром $s, в котором передается сообщение об ошибке.

Теперь, если все правильно, мы описываем необходимые переменные и rfc заголовки письма, после чего отправляем сообщение через sendmail и выводим сообщение о результате (отправлено/не отправлено). Здесь все просто и понятно из предыдущих примеров.

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

Комментарии

Оставьте свой комментарий
G
Guest453

Оу, спасибо большое за статью! Крайне полезно считаю.

D
dmitriy

Всем привет!
Данная связь заработала корректно только при разделении модуля на форму и файл-обработчик с небольшой его корректировкой. В дизайн встраивается сравнительно легко. Все работает как часы но...
После отправки письма выдает "Ваше письмо отправлено. Администратор ..." на БЕЛОМ ФОНЕ игнорируя дизайн сайта.
Все попытки правки кода приводят к "жесткому сопротивлению" вероятно со стороны php - файл просто "теряется" на сервере.
Вот код файла-обработчика:

<?

// если не было добавления сообщения, выводим форму
if (!$_POST['a']) show_form();

// проверяем данные формы
if (!$_POST['name']) show_form("Укажите Ваше имя!");
if (!$_POST['email']) show_form("Укажите Ваш email!");
if (!$_POST['message']) show_form("Вы не заполнили текст сообщения!");

// описываем переменные и rfc заголовки письма

// обратный адрес будет указанным адресом отправителя сообщения
$from = $_POST['email'];
$recipients = "besidetrue@besidetrue.ru"; // Ваш email
$subject="";
$body=$_POST['message'];
$headers = $_POST['subject'];

if(strpos($_SERVER['SERVER_SOFTWARE'], '(Win32)')===FALSE)
{
// открываем sendmail и отправляем письмо
$mail = popen("/usr/sbin/sendmail -i -f$from -- $recipients", 'w');
$text_headers = "from: $fromnsubject: $subject".$headers;
fputs($mail, $text_headers);
fputs($mail, "n");
fputs($mail, $body);

// проверяем на ошибку
$result = pclose($mail) >> 8 & 0xff;
}
else $result=(mail($recipients, $subject, $body, "from: ".$from."rn".$headers) ? FALSE : TRUE);
if ($result) echo "Сообщение не было отправлено!";
else echo "Ваше сообщение отправлено.Администратор свяжется с Вами в ближайшее время!";
?>
Я не знаю php то что-то удавалось лишь интуитивно. А здесь мне очень нужна помощь.
С уважением к сообществу.

Д
Дмитрий

Пацаны создаем форму и вставляем ее куда нам надо, форма выглядит:

<table width=450 cellpadding=0 cellspacing=1 bgcolor=#808080>
<form action="send.php" method=post>
<tr><td colspan=3 bgcolor=#B9F4C7 height=25 align=center>
Обратная связь</td></tr>
<tr bgcolor=#D1EFFA>
<td height=30 width=150 align=center> Ваше имя: *</td>
<td bgcolor=#D1EFFA> <input type=text name=name size=50></td>
</tr>
<tr bgcolor=#D1EFFA>
<td height=30 align=center> Ваш email: *</td>
<td bgcolor=#D1EFFA> <input type=text name=email size=50></td>
</tr>
<tr bgcolor=#D1EFFA>
<td height=30 align=center> Ваш сайт:</td>
<td bgcolor=#D1EFFA> <input type=text name=domain size=50></td>
</tr>
<tr bgcolor=#D1EFFA>
<td height=30 colspan=2>
<table width=100% cellpadding=15 cellspacing=5><tr><td>
Ваше сообщение: *
<textarea cols=50 rows=5 name=message></textarea>
</td></tr></table>
</td>
</tr>
<tr><td colspan=2 bgcolor=#B9F4C7 height=35 align=center>
<input type="submit" value="Отправить вопрос"></td></tr>
<input type=hidden name=a value=1>
</form>
</table>

Далее в маем случаи создаем фаил send.php (или другой свой файл, смотря что указали в поле action="") и туда вставляем скрипт php:

<code><?

function show_form($s="") {
if ($s) echo "Ошибка: $s";
?>
<?
exit();
};

// если не было добавления сообщения, выводим форму
if (!$_POST['a']) show_form();

// проверяем данные формы
if (!$_POST['name']) show_form("Укажите Ваше имя!");
if (!$_POST['email']) show_form("Укажите Ваш email!");
if (!$_POST['message']) show_form("Вы не заполнили текст сообщения!");

// описываем переменные и rfc заголовки письма

// обратный адрес будет указанным адресом отправителя сообщения
$from = $_POST['email'];
$recipients = " brazwoor@gmail.com"; // Ваш email
$subject="Тема письма";
$body=$_POST['message'];
$headers = "content-type: text/plain; charset=windows-1251"; // кодировка письма

if(strpos($_SERVER['SERVER_SOFTWARE'], '(Win32)')===FALSE)
{
// открываем sendmail и отправляем письмо
$mail = popen("/usr/sbin/sendmail -i -f$from -- $recipients", 'w');
$text_headers = "from: $fromnsubject: $subject".$headers;
fputs($mail, $text_headers);
fputs($mail, "n");
fputs($mail, $body);

// проверяем на ошибку
$result = pclose($mail) >> 8 & 0xff;
}
else $result=(mail($recipients, $subject, $body, "from: ".$from."rn".$headers) ? FALSE : TRUE);

if ($result) echo "Сообщение не было отправлено!";
else echo "Спасибо, Ваше сообщение отправлено. Администратор свяжется с Вами в ближайшее время!";
?></code>

ВСЕ РАБОТАЕТ! не забывайте только емаил на свой исправлять.

A
Alena

Здравствуйте! Установила на страницу этот код, все работает, письмо отправляется,но на указанную мной почту приходит пустое письмо, в теме сообщения выходит "content-type: text/plain; charset='windows-1251'", а адрес отправителя вот такой "undisclosed-recipients:". Подскажите пожалуйста в чем ошибка. Может я что-то где-то не прописала???

Н
Николай

Можно сделать и проще.

Файл с формой:

<html>
<body>
<p style="color:#FF0000"> <strong>Вы можете отправить мне сообщение, заполнив следующую форму:</strong></p>
<form method="post" action="1.php">
<strong>Ваше имя:</strong>
<input type="text" name="name" size="30"/>
<br />
<strong>Ваш e-mail (для ответа):</strong><br />
<input name="email" type="text" size="30" />
<br />
<strong>Ваше сообщение:</strong><br />
<textarea name="mess" rows="3" cols="30"></textarea>
<p>
<input type="submit" value="Отправить сообщение"/>
</p>
</form>
</body>
</html>
Обработчик:

<?php
if (isset($_POST['name'])) {$name = $_POST['name'];}
if (isset($_POST['email'])) {$email = $_POST['email'];}
if (isset($_POST['mess'])) {$mess = $_POST['mess'];}
if (empty($name)){
exit("Вы ввели не всю информацию!<a href=send.html>Вернуться к заполнению формы</a>");
}
if (empty($email)){
exit("Вы ввели не всю информацию!<br><a href=send.html>Вернуться к заполнению формы</a>");
}
if (empty($mess)){
exit("Вы ввели не всю информацию!<br><a href=send.html>Вернуться к заполнению формы</a>");
}
else{
$to = "lucky_nick@ukr.net"; /*Указать свой адрес*/
$subject = "Сообщение с вашего сайта";
$message = "Имя пославшего: $name nЭлектронный адрес: $email nСообщение: $mess";
$send = mail ($to, $subject, $message, "Content-type:text/plain; Charset=windows-1251 rn");
}
if ($send == 'true')
{
echo "Спасибо за отправку вашего сообщения!<br><a href=index.html>Вернуться на главную!</a>";
}
else
{
echo "Ошибка. Сообщение не отправлено!";
}
?>
При добавлении на сайт форму встраиваем куда удобно, обращаем внимание на имя файла, куда она будет встраиватся (тут прописано send.html). Создаем файл, и добавляем скрипт обработчика, обзываем его 1.php Не забудьте вставить свой адрес электронной почты))

М
Максим

А как организовать проверку капчей?

B
BATAZOR

А вот если сайт на utf-8 то в каком формате отправлять сообщения? utf-8 или windows-1251

J
Jekaterina

У меня не приходят отосланные письма 🙁
адрес почты совпадает с доменом.

Может кто-то помочь решить проблему?

W
Well

Хозяйке на заметку:

если всё сделали правильно и после отправки пишет "Спасибо, Ваше сообщение отправлено. Администратор свяжется с Вами в ближайшее время!", но на ящик в $recipients письмо не приходит, то вероятная причина в том, что вы указали в почтовый ящик на домене, отличном от домена вашего сайта.

Другими словами, если адрес сайта например "www.sitedomain.ru" то функция mail() на некоторых хостингах (в моём случае timeweb) будет работать только с почтовыми ящиками "someaddress@SITEDOMAIN.ru" и никак иначе (someaddress@mail.ru - работать не будет). При этом функция mail() вернёт true, соответственно сообщение будет что письмо якобы отправлено.
Спасибо автору за толковую статью!

Ю
Юрий

Подскажите пожалуйста, каким образом сделать форму обратной связи с раскрывающимся списком выбора темы сообщения, но чтобы каждая тема соответствовала бы конкретному емайл адресу. Т.е. чтобы каждый пользователь из техподдержки получал бы ему адресованное письмо. Буду признателен за Ваш ответ. Спасибо!

Загрузить еще