Отправка email через php. Простейшая форма отправки данных на почту при помощи HTML и PHP
Отправка писем при помощи PHP
Общие возможности
Рано или поздно каждый владелец сайта сталкивается с необходимостью отправки писем непосредственно с сайта через скрипт, а не через почтовые программы. Это могут быть письма, отправляемые скриптом гостевой книги, сообщающее владельцу сайта что у него в гостевой появилось новое сообщение, или форумом, для оповещения о новом вопросе.
Во всех этих случаях необходима именно автоматическая отправка писем минуя разнообразные почтовые программы и утилиты. Сделать это можно при помощи функции mail() , которую мы сейчас и будем изучать.
Синтаксис функции mail():
Bool mail(string $to, string $subject, string $msg [, string $header]);
Чтобы было более понятно, что из себя представляют заголовки, и где они находятся в письме, откройте почтовый клиент и посмотрите на любое письмо в том виде, как оно пришло (Для Outlook это можно сделать нажав правой клавишей мыши на сообщение->Свойства->Подробно->Исходное сообщение ).
Как мы видим, письмо представляет простой текстовой файл, состоящий из двух общих разделов: Вверху идут заголовки письма, затем через две строки идет само письмо.
Заголовков письма достаточно много, но не все они используются при написании скрипта отправки почты.
Вот некоторые наиболее часто используемые:
- From: "Имя пользователя отправителя" <Обратный адрес отправителя>
- To: <Адрес, по которому отправляют письмо>
- Subject: Тема письма
Решение проблемы кодировок
Я не зря выше привел пример отправки письма со словами латинского алфавита. Их любой почтовый клиент прочтет без труда. Но вот с русским алфавитом труднее. Русских кодировок существует огромное множество. И от того, насколько умело Вы перекодируете письмо, будет зависеть прочтет ли получатель его, или не будет возиться с установкой нужной кодировки и просто удалит его в корзину.
Кодировку письма задает заголовок Content-type :
$header="From: \"Evgen\" "; $header.="Content-type: text/plain; charset=\"windows-1251\""; $subject="Тема письма"; $msg="Сторака 1\nСтрока 2\nСтрока 3"; mail("
В заголовке мы указали, что тип письма будет простой текст, а кодировка - Windows.
Теперь наше письмо придет в понятной для почтового клиента кодировке.
Но стоит отметить, что в некоторых случаях в правильной кодировке будет отображено только само письмо. Заголовок же так и останется нечитаемым. Связано это с тем, где расположен заголовок Content-type относительно заголовка Subject , который и содержит тему письма. Дело в том, что существуют почтовые программы, которые понимают заголовок Content-type , но не понимают русский текст в поле Subject , если это поле стоит до Content-type . В то же время, другие почтовые программы обязывают нас задавать Content-type последним заголовком в списке. Чтобы обойти эти препятствия, можно разместить поле Content-type сразу в начале и в конце списка заголовков:
$subject="Тема письма"; $header="Content-type: text/plain; charset=\"windows-1251\""; $header.="From: Evgen "; $header.="Subject: $subject"; $header.="Content-type: text/plain; charset=\"windows-1251\""; $msg="Сторака 1\nСтрока 2\nСтрока 3"; mail(" ", $subject, $msg, $header);
Теперь это письмо прочтет любая почтовая программа!
Однако заметим, что это является извращением, и если это читает несколько кривых почтовых программ, которые нашли составители то это не значит что должны читать все.
Знакомство с php-функцией mail() и простейший пример её использования для отправки писем по электронной почте. Что лучше или Sendmail vs mail.
PHP-функция mail() позволяет вам отправлять письма на указанный адрес электронной почты.
Синтаксис :
Bool mail (string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]]);
Параметры :
- to
— адрес электронной почты получателя письма в соответствии с форматом RFC 2822. Например
:
- [email protected]
- [email protected], [email protected]
- Имя пользователя < [email protected]>
- Имя пользователя < [email protected]> , Имя ещё одного пользователя < [email protected]>
- subject — тема отправляемого письма в соответствии с форматом RFC 2047
- message
— содержание отправляемого письма. Каждая строка должна быть не длиннее 70 символов и заканчиваться символом новой строки (\n).
Только для Windows : Когда PHP обращается к SMTP серверу напрямую, точка в начале строки удаляется. Для борьбы с этим нюансом, следует использовать замену на двойную точку в начале строки.
$message = str_replace ("\n.", "\n..", $message);
- additional_headers (не обязательно) – строка, которая будет добавлена после заголовков письма. Обычно используется для добавления дополнительных заголовков (From, Cc и Bcc). Строки должны быть разделены CRLF (\r\n).
- additional_parameters (не обязательно) – дополнительные параметры, используемые программой назначенной для отправки писем.
Возвращает : TRUE если письмо отправлено успешно или FALSE если нет. Следует отметить, если письмо успешно поставлено в очередь на отправление, это не значит, что оно достигнет адресата.
Теперь, когда мы разобрались в теории, можно приступить к практике. Но для начала я хочу привести парочку полезных функций, которые позволят в значительной степени облегчить нашу задачу.
Пример : php-функция MIME base64 кодирования, с учетом кодировки
Function mime_base64($string, $charset="windows-1251") { return "=?" . $charset . "?B?" . base64_encode(trim($string)) . "?="; }
Одна из проблем, возникающих при отправке почты, заключается в формировании заголовка письма. В частности, заголовок, имена отправителя и получателя, написанные кириллицей могут быть распознаны почтовым клиентом получателя в искаженном виде. Для того чтобы избежать этой проблемы, можно воспользоваться MIME base64 кодированием, преобразующее последовательность байт в последовательность печатных ASCII символов.
Function is_email($string) { return preg_match("/^()+([\.a-zA-Z0-9_-])*@()+(\.+)*\.({2,6})$/", $string); }
С эти тоже разобрались. А теперь то, ради чего и писалась данная заметка.
Пример : отправка писем с помощью php-функции mail()
$charset = "windows-1251";
$from = mime_base64("Имя отправитель", $charset) . " Письмо отправлено. Произошла ошибка.
Думаю, что комментарии излишни, так как я и без того уделил достаточно много внимание различным деталям. Варианты набора RFC-заголовков могут отличаться, но на локальном сервере я получил следующее:
X-Sendmail-Cmdline: sendmail.pl -t -i
To: =?windows-1251?B?yOz/IO/u6/P36PLl6/w=?=
Sendmail vs php mail()
Напоследок небольшой ликбез. Sendmail является одним из почтовых серверов (MTA), в то время как php-функция mail() просто реализует процесс отправки писем через SMTP соединение. Понятно, что использование php-функции является удобным, но далеко не оптимальным решением. Обычно mail() используется в тех случаях, когда речь не заходит о масштабных рассылках.
Содержит только текст (малый вес сообщения)$name = "Пётр Петрович"; // необязательная переменная в качестве примера вставки в сообщение
$subject = "Тема сообщения"; //тема сообщения
$message = "Здравствуйте,".$name."!\n
Просто спросить как дела!\n
С уважением, Иван Иванович";//содержание сообщения
mail($email, $subject, $message, "From: [email protected]\nReply-To: [email protected]\nContent-type:text/plain; Charset=utf-8\r\n"); //отправляем сообщение
?>
2. Отправка письма mail php Тип text/html
Могут содержать графические html-элементы, сслыки и тп.Больше объём передаваемой информации
// отправка нескольким адресатам
$to = "[email protected]" . ", "; // кому отправляем
$to .= "[email protected]" . ", "; // Внимание! Так пишем второй и тд адреса
// не забываем запятую. Даже в последнем контакте лишней не будет
// Для начинающих! $to .= точка в этом случае для Дописывания в переменную
// устанавливаем тип сообщения Content-type, если хотим
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=utf-8 \r\n";
// дополнительные данные
$headers .= "From: yournick
$headers .= "Cc: [email protected]" . "\r\n"; // копия сообщения на этот адрес
$headers .= "Bcc: [email protected]\r\n"; // скрытая копия сообщения на этот
mail($to, $subject, $message, $headers);
?>
3. Как использовать в письме CSS?
Тут я хочу сразу немного огорчить Вас - CSS в привычном для Вас виде не стоит использовать. Mail, Yandex, Google, Outlook - выкидывают стили из писем. Однако, есть выход.Выполним несколько условий:
1)
Надеюсь не нужно пояснять, что используем Content-type: text/html
2) Вспоминаем, что такое table вёрстска. Теперь все стили вписываем только в неё. Можно также вспомнить center , font .
От кого: Иванов Иван Иванович |
Адрес: [email protected] |
Сообщение: Смотрим и радуемся |
С div то же самое
3) В примере выше с отправкой письма приводилась данная строка. Так вот её не забываем
$headers = "MIME-Version: 1.0" . "\r\n";
4) Используем HTML 3.2 . Вставляем в начало html письма.
5)
В качестве background - можно цвет. Хотите фон-изображение - тогда делайте весь текст и фон изображением. Как вариант: можно указать background-image для body.
6) У единственной в ячейке картинки в Gmail появляется 3px отступ снизу, чтобы избежать этого указываем ей
Одной из самых востребованных функций на сайте является форма заявки или заказа, данные из которой отправляются на почту владельцу сайта. Как правило такие формы являются простыми и состоят из двух трех полей для ввода данных. Как же создать такую форму заказа? Здесь потребуется использование языка разметки HTML и языка программирования PHP.
Язык разметки HTML сам по себе несложен, нужно всего лишь разобраться в том как и где ставить те или иные теги. С языком программирования PHP все немного сложнее.
Для программиста создать такую форму не составит труда, а вот HTML верстальщику может показаться сложным некоторые действия.
Создаем форму отправки данных в html
Первая строка будет следующей
Теперь соберем все вместе.
Теперь сделаем так, чтобы поля в форме стали обязательными для заполнения. Имеем следующий код:
Создаем файл, принимающий данные из HTML формы
Это будет файл с именем send.php
В файле на первом этапе нужно принять данные из пост массива. Для этого создаем две переменные:
$fio = $_POST["fio"];
$email = $_POST["email"];
Перед названиями переменных в php ставиться знак $, в конце каждой строки ставиться точка с запятой. $_POST это массив в который передаются данный из формы. В форме html при этом указан метод отправки method="post". Так, приняты две переменные из формы html. Для целей защиты своего сайта нужно провести эти переменные через несколько фильтров - функций php.
Первая функция преобразует все символы, которые пользователь попытается добавить в форму:
При этом новые переменные в php не создаются, а используются уже имеющиеся. Что сделает фильтр, он преобразует символ "<" в "<". Также он поступить с другими символами, встречающимися в html коде.
Вторая функция декодирует url, если пользователь попытается его добавить в форму.
$fio = urldecode($fio);
$email = urldecode($email);
Третей функцией мы удалим пробелы с начала и конца строки, если таковые имеются:
$fio = trim($fio);
$email = trim($email);
Существуют и другие функции, позволяющие отфильтровать переменные php. Их использование зависит от того, насколько вы опасаетесь того, что злоумышленник попытается добавить программный код в данную форму отправки данных на почту html.
Проверка данных, передаваемых от HTML формы в файл PHP
Для того, чтобы проверить, работает ли этот код, передаются ли данные можно просто их вывести на экран при помощи функции echo:
echo $fio;
echo "
";
echo $fio;
Вторая строка здесь нужна для того, чтобы разделить вывод переменных php на разные строки.
Отправляем полученные данные из формы HTML на почту при помощи PHP
Для отправки данных на почту нужно воспользоваться функцией mail в PHP.
mail("на какой адрес отправить", "тема письма", "Сообщение (тело письма)","From: с какого email отправляется письмо \r\n");
Например, нужно отправить данные на email владельца сайта или менеджера [email protected].
Тема письма должна быть понятной, а сообщение письма должно содержать то, что указал пользователь в HTML форме.
mail("[email protected]", "Заявка с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n");
Необходимо добавить условие, которе проверит отправилась ли форма при помощи PHP на указанные адрес электронной почты.
if (mail("[email protected]", "Заказ с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n"))
{
echo "сообщение успешно отправлено";
} else {
}
Таким образом программный код файла send.php, который отправит данные HTML формы на почту будет выглядеть следующим образом:
$fio = $_POST["fio"];
$email = $_POST["email"];
$fio = htmlspecialchars($fio);
$email = htmlspecialchars($email);
$fio = urldecode($fio);
$email = urldecode($email);
$fio = trim($fio);
$email = trim($email);
//echo $fio;
//echo "
";
//echo $email;
if (mail("[email protected]", "Заявка с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n"))
{ echo "сообщение успешно отправлено";
} else {
echo "при отправке сообщения возникли ошибки";
}?>
Три строки для проверки, передаются ли данные в файл закомментированы. При необходимости их можно удалить, так как они нужны были только для отладки.
Помещаем HTML и PHP код отправки формы в один файл
В комментариях к этой статье многие задают вопрос о том, как сделать, чтобы и HTML форма и PHP код отправки данных на почту находились в одном файле, а не двух.
Для реализации такой работы нужно поместить HTML код формы в файл send.php и добавить условие, которое будет проверять наличие переменных в массиве POST (этот массив передается из формы). То есть, если переменные в массиве не существуют, то нужно показать пользователю форму. Иначе нужно принять данные из массива и отправить их адресату.
Давайте посмотрим как изменить PHP код в файле send.php:
//проверяем, существуют ли переменные в массиве POST
if(!isset($_POST["fio"]) and !isset($_POST["email"])){
?> } else {
//показываем форму
$fio = $_POST["fio"];
$email = $_POST["email"];
$fio = htmlspecialchars($fio);
$email = htmlspecialchars($email);
$fio = urldecode($fio);
$email = urldecode($email);
$fio = trim($fio);
$email = trim($email);
if (mail("[email protected]", "Заявка с сайта", "ФИО:".$fio.". E-mail: ".$email ,"From: [email protected] \r\n")){
echo "Сообщение успешно отправлено";
} else {
echo "При отправке сообщения возникли ошибки";
}
}
?>
Существование переменной в POST массиве мы проверяем PHP функцией isset(). Восклицательный знак перед этой функцией в условии означает отрицание. То есть, если переменной не существует, то нужно показать нашу форму. Если бы я не поставил восклицательный знак, то условие дословно означало бы - "если существует, то показать форму". А это неправильно в нашем случае. Естественно, что вы можете переименовать его в index.php. Если будуту переименовывать файл, то не забудьте переименовать название файла и в строке