
PHPMailer — пожалуй, самая популярная открытая PHP‑библиотека для отправки электронных писем. Она впервые вышла в 2001 году и с тех пор стала любимым инструментом PHP‑разработчиков для программной отправки писем — наряду с другими популярными решениями вроде Swiftmailer (поддержка прекращена с ноября 2021 года).
В этой статье мы разберём, почему стоит использовать PHPMailer вместо встроенной функции mail(), и покажем примеры кода для работы с этой библиотекой.
В большинстве случаев библиотека выступает альтернативой встроенной функции PHP mail(), но есть ситуации, когда mail() недостаточно гибка для решения нужных задач.
mail() — нет. Разработчикам PHP часто приходится вручную формировать строку $headers при отправке писем через mail(), что требует множества экранирований символов. С PHPMailer эта задача решается гораздо проще.mail() нужно писать громоздкий код для обработки вложений и HTML‑писем (экранирование символов, кодирование и форматирование). PHPMailer делает это безболезненно.Вы можете установить PHPMailer с помощью Composer:
composer require phpmailer/phpmailerВот простейший пример отправки письма с локального веб‑сервера:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require_once "vendor/autoload.php";
// Создаём объект PHPMailer. Аргумент true включает обработку исключений
$mail = new PHPMailer(true);
// Адрес и имя отправителя
$mail->From = "from@yourdomain.ru";
$mail->FromName = "Полное имя";
// Адреса и имена получателей
$mail->addAddress("recipient1@example.ru", "Имя получателя");
$mail->addAddress("recipient2@example.ru"); // Имя получателя необязательно
// Адрес для ответов
$mail->addReplyTo("reply@yourdomain.ru", "Ответ");
// Копии (CC и BCC)
$mail->addCC("cc@example.ru");
$mail->addBCC("bcc@example.ru");
// Отправка HTML или текстового письма
$mail->isHTML(true);
$mail->Subject = "Тема письма";
$mail->Body = "<i>Тело письма в формате HTML</i>";
$mail->AltBody = "Это текстовая версия содержимого письма";
try {
$mail->send();
echo "Письмо успешно отправлено";
} catch (Exception $e) {
echo "Ошибка отправки: " . $mail->ErrorInfo;
}Комментарии в коде достаточно подробно объясняют, что происходит: здесь задаётся тема письма, адрес отправителя, адреса получателей, HTML‑тело письма и обработка ошибок.
Пример отправки письма с вложениями:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require_once "vendor/autoload.php";
$mail = new PHPMailer;
$mail->From = "from@yourdomain.com";
$mail->FromName = "Полное имя";
$mail->addAddress("recipient1@example.com", "Имя получателя");
// Указываем путь к файлам и их имена для вложений
$mail->addAttachment("file.txt", "File.txt");// Имя файла необязательно
$mail->addAttachment("images/profile.png");
$mail->isHTML(true);
$mail->Subject = "Тема письма";
$mail->Body = "<i>Тело письма в формате HTML</i>";
$mail->AltBody = "Это текстовая версия содержимого письма";
try {
$mail->send();
echo "Письмо успешно отправлено";
} catch (Exception $e) {
echo "Ошибка отправки: " . $mail->ErrorInfo;
}В этом примере мы прикрепляем два файла:
file.txt — находится в той же директории, что и скрипт;images/profile.png — находится в папке images относительно директории скрипта.Чтобы добавить вложения, достаточно вызвать метод addAttachment, передав путь к файлу в качестве аргумента. Для нескольких файлов метод вызывается несколько раз.
В примерах выше мы использовали класс Exception для отладки: любые возникающие ошибки помогают выявить проблемы. Мы также передали аргумент true в конструктор, чтобы получать более подробные исключения.
Чаще всего возникает ошибка, связанная с выполнением функции mail() в фоновом режиме:
Ошибка отправки: Could not instantiate mail function.Для получения подробной информации об ошибке можно добавить в блок catch следующий код:
print_r(error_get_last());Обычно проблема связана с отсутствием настроенного почтового сервера. В этом случае error_get_last() вернёт что‑то вроде:
Array (
[type] => 2
[message] => mail(): Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set()
[file] => OUR_PATH\vendor\phpmailer\phpmailer\src\PHPMailer.php
[line] => 863
)Эту проблему легко решить, используя SMTP.
$mail->ErrorInfo может возвращать сообщения об ошибках на 43 разных языках.
Чтобы выводить ошибки на другом языке, скопируйте папку с языками из исходного кода в директорию проекта.
Например, чтобы выводить ошибки на русском, установите русский язык для объекта:
$mail->setLanguage("ru");Вы также можете добавить собственные языковые файлы в папку с языками.
Можно использовать почтовый сервер другого хоста для отправки писем. Для этого нужна аутентификация. Например, для отправки через сервер Gmail потребуется аккаунт Gmail.
SMTP — протокол, который почтовые клиенты используют для отправки запросов на отправку писем почтовому серверу. После проверки сервер отправляет письмо на целевой сервер.
Пример отправки письма через сервер Gmail с вашего домена (локальный сервер не нужен):
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require_once "vendor/autoload.php";
$mail = new PHPMailer(true);
// Включаем отладку SMTP
$mail->SMTPDebug = 3;
// Устанавливаем использование SMTP
$mail->isSMTP();
// Хост SMTP
$mail->Host = "smtp.gmail.com";
// Аутентификация требуется
$mail->SMTPAuth = true
// Логин и пароль
$mail->Username = "name@gmail.com";
$mail->Password = "super_secret_password";
// Если SMTP требует шифрования TLS, устанавливаем его
$mail->SMTPSecure = "tls";
// Порт для подключения
$mail->Port = 587;
$mail->From = "name@gmail.com";
$mail->FromName = "Полное имя";
$mail->addAddress("name@example.com", "Имя получателя");
$mail->isHTML(true);
$mail->Subject = "Тема письма";
$mail->Body = "<i>Тело письма в формате HTML</i>";
$mail->AltBody = "Это текстовая версия содержимого письма";
try {
$mail->send();
echo "Письмо успешно отправлено";
} catch (Exception $e) {
echo "Ошибка отправки: " . $mail->ErrorInfo;
}Gmail требует шифрования TLS через SMTP, поэтому мы устанавливаем соответствующие настройки. Перед отправкой через SMTP нужно узнать:
Важно: если у вас включена двухфакторная аутентификация в Gmail, вы не сможете использовать SMTP с логином и паролем. Потребуется дополнительная настройка.
Одно из главных преимуществ использования удалённого SMTP вместо локального mail() — борьба со спамом. Если вы отправляете письмо через функцию mail(), а домен в поле «От» отличается от имени локального сервера, фильтры получателя могут пометить письмо как спам.
Например, если вы отправляете с сервера с именем хоста example.com письмо от name@gmail.com на name@yandex.ru, сервер Яндекс может пометить его как спам. Хотя вы владеете адресом name@gmail.com, Яндекс не может это проверить.
PHPMailer поддерживает проверку подлинности POP‑before‑SMTP для отправки писем. Иными словами, вы можете пройти аутентификацию через POP и отправить письмо через SMTP.
Однако PHPMailer не поддерживает получение писем с почтовых серверов по протоколу POP3. Библиотека предназначена только для отправки.
Если вы PHP‑разработчик, вам наверняка придётся отправлять письма программно. Можно использовать сторонние сервисы вроде Mandrill или SendGrid, но иногда это невозможно. Создавать собственную библиотеку для отправки писем — ещё менее подходящий вариант.
Именно здесь на помощь приходят PHPMailer и его альтернативы (Zend Mail, Swift Mailer и другие).
Узнать больше о API библиотеки можно: