Отправка mail() в php
Рассмотрим, как отправить почтовое сообщение с помощью php функции mail(). В данной статье мы создадим максимально «белую» отправку, чтобы ваше письмо не попало в папку «Спам».
Содержание:
- создание файла mail.php и основных переменных;
- формирование текстовой версии письма (text/plain) и таблицы для HTML-версии;
- доработка HTML-версии почтового сообщения;
- создание заголовков;
- формирование итогового сообщения письма;
- отправка mail();
- итоговый код.
Какие мы решим возможные проблемы:
- HTML-only message, but there is no HTML tag.
Ваше сообщение должно содержать тег <html>. - Message only has text/html MIME parts.
Вам нужно добавить текстовую версию письма (text/plain). - HTML and text parts are different.
Убедитесь, что ТЕКСТОВАЯ версия почтового сообщения похожа на HTML версию. - При отправке на почту gmail:
Вы не можете использовать Gmail адрес, если Вы не отправляете от Gmail. - PHP_ORIG_SCRIPT
При создании нашего php кода для отправки функции mail() мы учтём моменты выше, чтобы минимизировать процент попадания письма в папку «Спам».
Создание файла mail.php и основных переменных
Создадим в корне сайта файл mail.php и добавим в него следующий код.
<?php
// Получатель(ли)
$admin_email = "your@mail.com";
// Тема письма
$form_subject = "Заявка с сайта site-name.ru";
// От кого
$project_name = "email@mailer.com";
// HTML письма
$html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="ru">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>' . $form_subject . '</title>
</head>
<body>';
Мы создали 4 переменных:
- $admin_email — список получателей (через запятую);
- $form_subject — тема письма;
- $project_name — отправитель письма;
- $html — начало HTML письма (далее мы его будет дополнять контентом).

Формирование текстовой версии письма (text/plain) и таблицы для HTML-версии
Сформируем таблицу $table для HTML-версии (text/html) почтового сообщения.
Затем в переменную $plain_text добавим текстовую версию. Всё это сделаем в цикле foreach. Также предусмотрим возможный вариант $_POST[«value»] в виде массива (значений чекбоксов).
$c = true;
$plain_text = "";
$table = "";
foreach ($_POST as $key => $value) {
if (is_array($value)) $value = implode(", ", $value);
if ($value != "" && $key != "project_name" && $key != "admin_email" && $key != "form_subject") {
// text/html
$table .= (($c = !$c) ? '<tr>' : '<tr style="background-color: #f8f8f8;">') . '
<td style="padding: 10px; border: #e9e9e9 1px solid;"><b>' . $key . '</b></td>
<td style="padding: 10px; border: #e9e9e9 1px solid;">' . $value . '</td>
</tr>';
// text/plain
$plain_text .= $key . ": " . $value . "\r\n";
}
}
Таким образом, мы обработали полученные с фронтенда данные формы.
Доработка HTML-версии почтового сообщения
В первом пункте данной статьи мы создали файл mail.php и объявили основные переменные для нашего файла, в числе которых была переменная $html. Во втором пункте мы создали переменную $table, в которой сформировали HTML-таблицу из name и value. Теперь нам необходимо добавить таблицу с данными к переменной $html.
$html .= '<table width="100%">
<tr style="text-align: center;">
<td style="padding: 0 10px; width: 100%; border: #e9e9e9 1px solid;" colspan="2">
<h2>" . $form_subject . "</h2>
</td>
</tr>
' . $table . '
</table>
</body>
</html>';
function adopt($text)
{
return "=?UTF-8?B?" . Base64_encode($text) . "?=";
}
$boundary = "--" . md5(uniqid(time())); // генерируем разделитель
Так же мы добавили функцию adopt для кодирования темы письма и сгенерировали разделитель, т.к. почтовое сообщение будет состоять из нескольких частей Content-Type: multipart/alternative.
Создание заголовков почтового письма
Сформируем заголовки в виде массива (для PHP >= 7.2).
$headers = array(
"MIME-Version" => "1.0",
"Date" => date("r (T)"),
"From" => "Имя отправителя (компании) <" . $project_name . ">",
"Reply-To" => $project_name,
"X-Mailer" => "PHP/" . phpversion(),
"Content-Type" => "multipart/alternative; boundary=" . $boundary . "",
);
Для более старых версий php необходимо создавать $headers без использования массива. В конце каждой строки нужно добавлять rn.
$headers .= "MIME-Version: 1.0" . "\r\n";
$headers .= "Date: " . date("r (T)") . "\r\n";
$headers .= "From: Имя отправителя (компании) <" . $project_name . ">" . "\r\n";
$headers .= "Reply-To: " . $project_name . "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
$headers .= 'multipart/alternative; boundary="' . $boundary . '"';
Формирование итогового сообщения письма
Собираем воедино сообщение, которое будем использовать для отправки 3 параметром функции mail().
// Текстовая версия письма
$message_plain_text .= "--$boundary" . "\n";
$message_plain_text .= "Content-Type: text/plain; charset=utf-8" . "\n";
$message_plain_text .= "Content-Transfer-Encoding: 8bit" . "\n\n";
$message_plain_text .= $form_subject . "\r\n" . $plain_text . "\n";
// HTML-версия письма
$message_html .= "--$boundary" . "\n";
$message_html .= "Content-Type: text/html; charset=utf-8" . "\n";
$message_html .= "Content-Transfer-Encoding: 8bit" . "\n\n";
$message_html .= $html . "\n";
$multipart_alternative = $message_plain_text . $message_html . "--$boundary--" . "\n";
На что стоит обратить внимание:
Желательно чтобы заголовки From, Reply-To и Return-Path совпадали.
Только вместо Return-Path мы укажем обратный адрес e-mail в 5 параметре функции mail(). Это позволит избежать проблему №4 в начале данной статьи.
Отправка mail() в php с проверкой
Все необходимые переменные для заполнения параметров мы подготовили, осталось отправить письмо и в случае ошибки вернуть сообщение об этом.
if (!mail($admin_email, adopt($form_subject), $multipart_alternative, $headers, "-f " . $project_name)) {
$error = error_get_last()["message"];
print_r($error);
}
Итоговый код
В результате наш mail.php должен выглядеть примерно так:
<?php
// Получатель(ли)
$admin_email = "your@mail.com";
// Тема письма
$form_subject = "Заявка с сайта site-name.ru";
// От кого
$project_name = "email@mailer.com";
// HTML письма
$html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="ru">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>' . $form_subject . '</title>
</head>
<body>';
$c = true;
$plain_text = "";
$table = "";
foreach ($_POST as $key => $value) {
if (is_array($value)) $value = implode(", ", $value);
if ($value != "" && $key != "project_name" && $key != "admin_email" && $key != "form_subject") {
// text/html
$table .= (($c = !$c) ? '<tr>' : '<tr style="background-color: #f8f8f8;">') . '
<td style="padding: 10px; border: #e9e9e9 1px solid;"><b>' . $key . '</b></td>
<td style="padding: 10px; border: #e9e9e9 1px solid;">' . $value . '</td>
</tr>';
// text/plain
$plain_text .= $key . ": " . $value . "\r\n";
}
}
$html .= '<table width="100%">
<tr style="text-align: center;">
<td style="padding: 0 10px; width: 100%; border: #e9e9e9 1px solid;" colspan="2">
<h2>" . $form_subject . "</h2>
</td>
</tr>
' . $table . '
</table>
</body>
</html>';
function adopt($text)
{
return "=?UTF-8?B?" . Base64_encode($text) . "?=";
}
$boundary = "--" . md5(uniqid(time())); // генерируем разделитель
$headers = array(
"MIME-Version" => "1.0",
"Date" => date("r (T)"),
"From" => "Имя отправителя (компании) <" . $project_name . ">",
"Reply-To" => $project_name,
"X-Mailer" => "PHP/" . phpversion(),
"Content-Type" => 'multipart/alternative; boundary="' . $boundary . '"',
);
// Текстовая версия письма
$message_plain_text .= "--$boundary" . "\n";
$message_plain_text .= "Content-Type: text/plain; charset=utf-8" . "\n";
$message_plain_text .= "Content-Transfer-Encoding: 8bit" . "\n\n";
$message_plain_text .= $form_subject . "\r\n" . $plain_text . "\n";
// HTML-версия письма
$message_html .= "--$boundary" . "\n";
$message_html .= "Content-Type: text/html; charset=utf-8" . "\n";
$message_html .= "Content-Transfer-Encoding: 8bit" . "\n\n";
$message_html .= $html . "\n";
$multipart_alternative = $message_plain_text . $message_html . "--$boundary--" . "\n";
if (!mail($admin_email, adopt($form_subject), $multipart_alternative, $headers, "-f " . $project_name)) {
$error = error_get_last()["message"];
print_r($error);
}
PHP_ORIG_SCRIPT
Для удаления заголовка X-PHP-Originating-Script существует 2 способа
(если знаете ещё, поделитесь в комментариях):
- редактирование php.ini
- редактирование .htaccess
php.ini
mail.add_x_header Off
.htaccess
php_flag mail.add_x_header Off
Чтобы не попасть в папку спам мы сделали всё от нас зависящее.
Остальные настройки вам необходимо делать на сервере: SPF, DKIM, DMARC, PTR.
Надеюсь, вам понравилась данная информация. Если вам интересна тема web-разработки, то можете следить за выходом новых статей в Telegram.
Поделиться с друзьями:
Статьи из данной категории:
Комментарии (4)
- Артем
- Андрей
- Only to top
- Вячеслав