Отправка почты в PHP: возможности и ограничения

Раздел: -> Работа с почтой

Основные способы отправки писем в PHP

Наиболее эффективное решение сегодня - использование библиотеки PHPMailer.

PHPMailer обеспечивает полный контроль над письмами: поддержка SMTP-аутентификации, шифрования, HTML-формата, вложений, удобная обработка ошибок. Библиотека активно развивается и рекомендуется для современных проектов. Установка через Composer:

composer require phpmailer/phpmailer

Php mail (отправка почты в php)

Пример простейшей отправки через SMTP-сервер Яндекс.Почты:

use PHPMailer\PHPMailer\PHPMailer;\nuse PHPMailer\PHPMailer\Exception;\n\nrequire 'vendor/autoload.php';\n\n$mail = new PHPMailer(true);\ntry {\n    $mail->isSMTP();\n    $mail->Host = 'smtp.yandex.ru';\n    $mail->SMTPAuth = true;\n    $mail->Username = 'user@yandex.ru';\n    $mail->Password = 'password';\n    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;\n    $mail->Port = 465;\n    $mail->setFrom('user@yandex.ru', 'Отправитель');\n    $mail->addAddress('recipient@example.com', 'Получатель');\n    $mail->Subject = 'Тестовое письмо';\n    $mail->Body = 'Привет! Это тест.';\n    $mail->send();\n    echo 'Письмо отправлено';\n} catch (Exception $e) {\n    echo "Ошибка: {$mail->ErrorInfo}";\n}

Message php (отправка сообщений в php)

Какой вопрос решает встроенная функция mail()?

Функция mail() доступна сразу после установки PHP без дополнительных библиотек. Подходит для простейших почтовых уведомлений на локальном сервере с установленным MTA (sendmail, postfix). Пример:

$to = 'user@example.com';\n$subject = 'Тема письма';\n$message = 'Текст письма';\n$headers = 'From: webmaster@example.com' . "\r\n" .\n           'Reply-To: webmaster@example.com' . "\r\n" .\n           'X-Mailer: PHP/' . phpversion();\nif (mail($to, $subject, $message, $headers)) {\n    echo 'Письмо отправлено';\n} else {\n    echo 'Ошибка отправки';\n}

Mail php p (отправка email через php)

Когда стоит использовать SwiftMailer?

SwiftMailer - библиотека с богатым функционалом, но её разработка остановлена (последняя версия 6.x). Тем не менее, на старых проектах она встречается. Пример отправки через SMTP:

require_once 'vendor/autoload.php';\n\n$transport = (new Swift_SmtpTransport('smtp.gmail.com', 587, 'tls'))\n    ->setUsername('your_email@gmail.com')\n    ->setPassword('your_password');\n$mailer = new Swift_Mailer($transport);\n$message = (new Swift_Message('Тема'))\n    ->setFrom(['from@example.com' => 'Отправитель'])\n    ->setTo(['to@example.com'])\n    ->setBody('Текст письма');\n$result = $mailer->send($message);\nif ($result) {\n    echo 'Письмо отправлено';\n} else {\n    echo 'Ошибка';\n}

Php mail sender (отправитель почты php)

Какой вариант выбирают для современных проектов Symfony?

Symfony Mailer - компонент фреймворка Symfony, может использоваться и отдельно. Предоставляет абстракцию над разными транспортами (SMTP, sendmail, mail()). Установка:

composer require symfony/mailer

Php mail https (отправка email через https в php)

Пример:

use Symfony\Component\Mailer\Transport;\nuse Symfony\Component\Mailer\Mailer;\nuse Symfony\Component\Mime\Email;\n\n$transport = Transport::fromDsn('smtp://user:pass@smtp.example.com:25');\n$mailer = new Mailer($transport);\n$email = (new Email())\n    ->from('from@example.com')\n    ->to('to@example.com')\n    ->subject('Тема')\n    ->text('Текст письма');\n$mailer->send($email);

Типичные проблемы и их решение

  • Письма не доходят (функция mail() возвращает true). Причина - письмо попадает в спам или игнорируется из-за отсутствия SPF/DKIM записи, некорректных заголовков. Решение - настроить SMTP через PHPMailer или использовать внешний почтовый сервис (SendGrid, Mailgun).
  • Ошибка Connection refused при SMTP. Убедитесь, что хост и порт верны, а на сервере не заблокирован исходящий трафик. Попробуйте использовать TLS на порту 587.
  • Ошибка аутентификации (535, 454). Проверьте логин и пароль, включите доступ для сторонних приложений в настройках почтового ящика.
  • Кириллица в теме письма отображается как &&&??? Используйте кодировку UTF-8 и правильные заголовки: $headers .= "Content-type: text/plain; charset=utf-8\r\n"; для mail(). В PHPMailer установите кодировку через $mail->CharSet = 'UTF-8';

Расширенные примеры работы с почтой в PHP

Пример 1. Отправка через mail() с полными заголовками и вложением (Base64)

Пример
// Формируем границу для multipart/mixed
$boundary = md5(uniqid(time()));
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: multipart/mixed; boundary=\"$boundary\"\r\n";
$headers .= "From: webmaster@example.com\r\n";

// Текстовое содержимое
$message = "--$boundary\r\n";
$message .= "Content-type: text/plain; charset=utf-8\r\n";
$message .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$message .= "Текст письма";

// Вложение (файл)
$file = '/path/to/file.pdf';
$content = file_get_contents($file);
$base64 = chunk_split(base64_encode($content));
$name = basename($file);
$message .= "--$boundary\r\n";
$message .= "Content-type: application/pdf; name=\"$name\"\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n";
$message .= "Content-Disposition: attachment; filename=\"$name\"\r\n\r\n";
$message .= $base64;
$message .= "--$boundary--";

mail('user@example.com', 'Тема', $message, $headers);

Результат: письмо с вложением, отправленное через локальный sendmail. Если sendmail не настроен, письмо не будет доставлено.

bool(true) // но доставка не гарантируется

Пример 2. PHPMailer: отправка HTML-письма с вложениями и альтернативным текстом

Пример
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);
try {
    $mail->isSMTP();
    $mail->Host = 'smtp.gmail.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'your@gmail.com';
    $mail->Password = 'app_password'; // Пароль приложения
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
    $mail->Port = 587;
    $mail->setFrom('your@gmail.com', 'Отправитель');
    $mail->addAddress('client@example.com', 'Клиент');
    $mail->addReplyTo('support@example.com', 'Поддержка');
    $mail->addAttachment('/path/to/invoice.pdf', 'Счет.pdf');
    $mail->isHTML(true);
    $mail->CharSet = 'UTF-8';
    $mail->Subject = 'Ваш заказ';
    $mail->Body = '

Спасибо за заказ!

Ваш счет во вложении.

'; $mail->AltBody = 'Спасибо за заказ! Счет во вложении.'; $mail->send(); echo 'Письмо отправлено'; } catch (Exception $e) { echo "Ошибка: {$mail->ErrorInfo}"; }

Результат: письмо с HTML-оформлением и вложением успешно доставлено (при корректных настройках).

Письмо отправлено

Пример 3. Отправка массовых писем с использованием очереди (PHPMailer + цикл)

Пример
$recipients = ['user1@domain.com', 'user2@domain.com', 'user3@domain.com'];
$mail = new PHPMailer();
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'bulk@example.com';
$mail->Password = 'password';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->setFrom('newsletter@example.com', 'Рассылка');
$mail->Subject = 'Новости';
$mail->Body = 'Текст рассылки';

foreach ($recipients as $email) {
    $mail->clearAddresses();
    $mail->addAddress($email);
    if(!$mail->send()) {
        echo "Ошибка отправки для $email: " . $mail->ErrorInfo . "\n";
    } else {
        echo "Успешно отправлено $email\n";
    }
}

Результат: последовательная отправка трёх писем. Для больших объёмов лучше использовать очередь задач (RabbitMQ, Gearman).

Успешно отправлено user1@domain.com
Успешно отправлено user2@domain.com
Ошибка отправки для user3@domain.com: SMTP Error...

Пример 4. Использование SwiftMailer с массивом получателей и поддержкой DKIM

Пример
require_once 'vendor/autoload.php';

$transport = (new Swift_SmtpTransport('smtp.mailtrap.io', 2525))
    ->setUsername('user')
    ->setPassword('pass');
$mailer = new Swift_Mailer($transport);

$message = (new Swift_Message('Подпись DKIM'))
    ->setFrom(['sender@example.com' => 'Отправитель'])
    ->setTo(['recipient@example.com', 'second@example.com'])
    ->setBody('Проверка DKIM-подписи', 'text/plain');

// Подписываем письмо DKIM (требуется приватный ключ)
$privateKey = file_get_contents('/path/to/private.key');
$signer = new Swift_Signers_DKIMSigner($privateKey, 'example.com', 'default');
$message->attachSigner($signer);

$result = $mailer->send($message);
echo "Отправлено получателей: $result\n";

Результат: письмо с корректной DKIM-подписью доставлено двум адресатам.

Отправлено получателей: 2

Пример 5. Symfony Mailer с шифрованием и несколькими вложениями

Пример
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mime\Email;

$transport = Transport::fromDsn('smtp://user:pass@smtp.sendgrid.net:587');
$mailer = new Mailer($transport);

$email = (new Email())
    ->from('noreply@example.com')
    ->to('admin@example.com')
    ->cc('cc@example.com')
    ->bcc('bcc@example.com')
    ->subject('Отчёт за месяц')
    ->html('

Отчёт

Показатели за месяц.

') ->attach(file_get_contents('/tmp/report.pdf'), 'report.pdf'); try { $mailer->send($email); echo 'Письмо отправлено'; } catch (\Exception $e) { echo 'Ошибка: ' . $e->getMessage(); }

Результат: письмо ушло основному получателю, копия и скрытая копия - отправлены.

Письмо отправлено

Пример 6. Логирование отправки через mail() с записью ошибок в файл

Пример
$to = 'webmaster@example.com';
$subject = '=?UTF-8?B?' . base64_encode('Кириллическая тема') . '?=';
$message = 'Привет';
$headers = "From: site@example.com\r\n";
$headers .= "Content-type: text/plain; charset=utf-8\r\n";
$headers .= "Content-Transfer-Encoding: 8bit\r\n";

$logFile = '/var/log/php_mail.log';
$success = mail($to, $subject, $message, $headers);
if ($success) {
    file_put_contents($logFile, date('Y-m-d H:i:s') . " SUCCESS - $to\n", FILE_APPEND);
} else {
    file_put_contents($logFile, date('Y-m-d H:i:s') . " FAIL - $to\n", FILE_APPEND);
}

Результат: в лог записана метка об успехе или неудаче. Лог помогает отследить проблемы отправки.

Содержимое /var/log/php_mail.log:
2025-04-06 10:15:23 SUCCESS - webmaster@example.com

Отправка почты в PHP - comments

En
Php mail (php)