PHPMailer – очень удобная и популярная библиотека для отправки e-mail сообщений с вашего сайта. В этой статье рассказаны основные настройки библиотеки и приведены примеры кода для отправки сообщений. PHPMailer имеет в своем ассортименте пожалуй всё, что можно пожелать от работы с почтой: отправка разными способами, через разные серверы в т.ч. через smtp, возможность шифровать и подписывать ваши письма, чтобы не попадали в спам и многое другое.
Скачать библиотеку PHPMailer можно с https://github.com/PHPMailer/PHPMailer (кнопка “Code” -> “Download ZIP”).
Для начала разберу пару простых примеров, чтобы было понятно, как отправлять письма с помощью PHPMailer.
Отправка писем через функцию mail() с помощью PHPMailer
Если вы хотите отправлять письма со своего хостинга через свой почтовый сервер, то всё довольно просто и будет выглядеть примерно так:
// Подключаем библиотеку PHPMailer
use PHPMailer\PHPMailer\PHPMailer;
require 'PHPMailer/PHPMailer.php';
// Создаем письмо
$mail = new PHPMailer();
$mail->setFrom('test@domain.ru', 'Иван Иванов'); // от кого (email и имя)
$mail->addAddress('test@ya.ru', 'Вася Петров'); // кому (email и имя)
$mail->Subject = 'Тест'; // тема письма
// html текст письма
$mail->msgHTML("<html><body>
<h1>Здравствуйте!</h1>
<p>Это тестовое письмо.</p>
</html></body>");
// Отправляем
if ($mail->send()) {
echo 'Письмо отправлено!';
} else {
echo 'Ошибка: ' . $mail->ErrorInfo;
}
Как видим, всё довольно просто: подключаем библиотеку, заполняем от кого, кому, тему и текст письма и отправляем. Отправка писем таким способом будет работать только с почтовых адресов вашего домена (если только они не привязаны к другим почтовикам).
Отправка писем через SMTP с помощью PHPMailer на примере Yandex и Google
Можно так же отправить письмо через другой почтовик, например, через Яндекс. Код будет выглядеть примерно так:
// Подключаем библиотеку PHPMailer
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
require 'PHPMailer/PHPMailer.php';
require 'PHPMailer/SMTP.php';
// Создаем письмо
$mail = new PHPMailer();
$mail->isSMTP(); // Отправка через SMTP
$mail->Host = 'smtp.yandex.ru'; // Адрес SMTP сервера
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'login'; // ваше имя пользователя (без домена и @)
$mail->Password = 'password'; // ваш пароль
$mail->SMTPSecure = 'ssl'; // шифрование ssl
$mail->Port = 465; // порт подключения
$mail->setFrom('login@ya.ru', 'Иван Иванов'); // от кого
$mail->addAddress('test@ya.ru', 'Вася Петров'); // кому
$mail->Subject = 'Тест';
$mail->msgHTML("<html><body>
<h1>Здравствуйте!</h1>
<p>Это тестовое письмо.</p>
</html></body>");
// Отправляем
if ($mail->send()) {
echo 'Письмо отправлено!';
} else {
echo 'Ошибка: ' . $mail->ErrorInfo;
}
Отправка писем через Google имеет один нюанс: нужно в аккаунте google разрешить доступ ненадежным приложениям. Для этого нужно зайти в свой аккаунт https://myaccount.google.com, перейти в безопасность, зайти в раздел “Ненадежные приложения, у которых есть доступ к аккаунту” и там переключить в “Разрешено”. На момент написания статьи это страница https://myaccount.google.com/u/0/lesssecureapps.
Дальше в php-программе отправка писем через PHPMailer происходит аналогично как через yandex, нужно только заменить настройки SMTP так:
$mail->Host = 'smtp.gmail.com'; // Адрес SMTP сервера
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'login'; // ваше имя пользователя
$mail->Password = 'password'; // ваш пароль
$mail->SMTPSecure = 'ssl'; // шифрование ssl
$mail->Port = 465; // порт подключения
Если первый раз запускаете программу отправки через smtp, тогда желательно перед отправкой дополнительно использовать $mail->SMTPDebug = 1; чтобы получать все сообщения клиента и smtp-сервера, т.е. на экран выведется весь процесс подключения, авторизации и т.д., что очень полезно для отладки вашей программы.
Отправка письма с вложением с помощью PHPMailer
Здесь всё довольно просто, нужно лишь использовать метод addAttachment. Приведу пример, заодно продемонстрировав еще несколько дополнительных возможностей:
// Подключаем библиотеку PHPMailer
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer/PHPMailer.php';
require 'PHPMailer/Exception.php';
// Создаем письмо
$mail = new PHPMailer;
$mail->CharSet = 'UTF-8';
$mail->setFrom('test@test.ru', 'Иван Иванов'); // от кого
$mail->addReplyTo('test@test.ru', 'Иван Иванов'); // обратный адрес
$mail->addAddress('test@ya.ru', 'Вася Петров'); // кому
$mail->Subject = 'Тест'; // тема
$mail->msgHTML(file_get_contents('contents.html'), __DIR__); // получаем "тело" письма из файла
$mail->AltBody = 'Письмо обычным текстом'; // письмо обычным текстом, если клиент не поддерживает html
$mail->addAttachment('my_file.txt'); // прикрепляем один файл
$mail->addAttachment('phpmailer.jpg'); // прикрепляем второй файл
// Отправляем
if ($mail->send()) {
echo 'Письмо отправлено!';
} else {
echo 'Ошибка: ' . $mail->ErrorInfo;
}
Адресов получателей можно добавить несколько с помощью addAddress. Или, если необходимо, можно наоборот, очистить все адреса получателей методом clearAddresses(). Очистить все вложения можно с помощью clearAttachments().
Так же можно использовать AddEmbeddedImage чтобы добавить в письмо вложение (обычно изображения), которое предназначено для использования в html-коде и не будет доступно для скачивания. Пример использования картинки в письме, не доступной для скачивания:
// Подключаем библиотеку PHPMailer
use PHPMailer\PHPMailer\PHPMailer;
require 'PHPMailer/PHPMailer.php';
//Создаем письмо
$mail = new PHPMailer;
$mail->IsHTML(true);
$mail->setFrom('test@test.ru', 'Иван Иванов');
$mail->addAddress('test@ya.ru', 'Вася Петров');
$mail->Subject = 'Test';
$mail->AddEmbeddedImage('phpmailer.jpg','testImage');
$mail->Body = '<p>Изображение в html-коде <img src="cid:testImage"></p>';
// Отправляем
$mail->send();
Таким образом, вы можете отправлять письма с изображениями, которые есть только в теле письма, но их нельзя скачать как вложение. Эти изображения можно использовать в любом месте html-кода письма, нужно лишь указывать вместо url-адреса cid изображения, который вы использовали в AddEmbeddedImage.
Отправка подписанного и зашифрованного письма через PHPMailer
По-умолчанию, PHPMailer шифрует все отправляемые письма. Отключить шифрование письма можно только при отправке писем через SMTP использовав код:
$mail->SMTPSecure = false;
$mail->SMTPAutoTLS = false;
Чтобы подписать письмо подписью DKIM, необходимо выполнить несколько действий:
- Сгенерировать приватный (private) и публичный (public) ключи для вашего домена
- Добавить DNS-запись для домена типа TXT с публичным ключом
- Настроить DKIM подпись в PHPMailer перед отправкой письма
Теперь опишу каждый шаг немного подробнее.
Генерация приватного и публичного ключей
Если у вас Linux-хостинг и есть доступ в Shell, то сгенерировать файлы ключей проще простого, нужно выполнить всего 2 команды с обычными правами своего пользователя:
openssl genrsa -out test-private.pem 1024
openssl rsa -in test-private.pem -out test-public.pem -pubout
Соответственно, test-private.pem и test-public.pem – это приватный и публичный ключи. Сохранить их нужно в папке, которая будет не доступна посетителям сайта или кому-то еще кроме вас.
Если нет возможности выполнить команды в shell, тогда чтобы сгенерировать приватный (private) и публичный (public) ключи и сохранить их в файлы, можно воспользоваться следующим кодом:
$domain = 'test.ru'; // ваш домен
$privatekeyfile = 'test-private.pem'; // имя файла, в который будет записан приватный ключ
$publickeyfile = 'test-public.pem'; // имя файла, в который будет записан публичный ключ
if (file_exists($privatekeyfile)) {
echo "<p>Using existing keys</p>";
$privatekey = file_get_contents($privatekeyfile);
$publickey = file_get_contents($publickeyfile);
} else {
echo "<p>Create keys</b>";
$pk = openssl_pkey_new(
[
'digest_alg' => 'sha256',
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
]
);
openssl_pkey_export_to_file($pk, $privatekeyfile);
$pubKey = openssl_pkey_get_details($pk);
$publickey = $pubKey['key'];
file_put_contents($publickeyfile, $publickey);
$privatekey = file_get_contents($privatekeyfile);
}
echo "<p>Private key (keep this private!):</p><pre>" . $privatekey . "</pre>";
echo "<p>Public key:</p><pre>" . $publickey . "</pre>";
Внимание! Не забудьте убедиться, что папка, в которую будут сохраняться файлы, доступна для записи.
Добавление DNS-записи с публичным ключом
DNS-запись нужна, чтобы почтовые серверы, которые будут получать ваши письма, смогли проверить подпись на письме, прочитав DNS-запись вашего домена. Как правило, DNS-запись можно добавить в панели управления вашим доменом, либо в панели управления хостингом. Если не знаете, как добавить запись, обратитесь в поддержку вашего хостинг-провайдера.
Нужно добавить DNS-запись следующего вида:
Имя записи: mail._domainkey.test.ru. (в конце точка “.”)
TTL: 3600 (или какое будет по-умолчанию)
Тип записи: TXT
Значение: v=DKIM1; h=sha256; t=s; p=ВАШ_ПУБЛИЧНЫЙ_КЛЮЧ
В имени записи test.ru нужно заменить на имя вашего домена. Слова “ВАШ_ПУБЛИЧНЫЙ_КЛЮЧ” вы заменяете на текст, который вы получили на предыдущем шаге после “Public key”, без “—–BEGIN PUBLIC KEY—–” и “—–END PUBLIC KEY—–“, только сам ключ. При этом все строчки ключа нужно соединить в одну длинную строку, чтобы переводов строки не было.
Настройка подписи DKIM в PHPMailer и отправка письма
Теперь осталось лишь сделать несколько настроек PHPMailer перед отправкой письма и оно будет подписано. Думаю, на приведенном примере будет всё понятно:
// Подключаем библиотеку
use PHPMailer\PHPMailer\PHPMailer;
require 'PHPMailer/PHPMailer.php';
// Создаем письмо
$mail = new PHPMailer;
$mail->CharSet = 'UTF-8';
$mail->setFrom('test@test.ru');
$mail->addAddress('test@ya.ru');
$mail->Subject = 'Это тест';
$mail->msgHTML('<p>Это тест</p>');
// Настройка DKIM подписи
$mail->DKIM_domain = 'test.ru';
$mail->DKIM_private = 'test-private.pem';
$mail->DKIM_selector = 'mail';
// Отправляем
$mail->send();
Разумеется, test.ru вы должны поменять на имя своего домена, а test-private.pem на полный путь и имя файла приватного ключа, который был создан на этапе генерации ключей.
Теперь, ваши письма, отправляемые через PHPMailer будут подписаны подписью DKIM вашим приватным ключом.