Реализация почтовой отправки в PHP

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

Основные подходы к отправке почты в PHP

Наиболее эффективное решение: использование PHPMailer

PHPMailer – это современная библиотека, которая поддерживает SMTP, вложения, HTML-шаблоны, шифрование TLS/SSL и корректную обработку ошибок. Она не зависит от настроек сервера (sendmail) и обеспечивает надёжную доставку писем.

Для подключения PHPMailer выполняется установка через Composer:

composer require phpmailer/phpmailer

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

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

require 'vendor/autoload.php';

$mail = new PHPMailer\PHPMailer\PHPMailer();
$mail->isSMTP();
$mail->Host = 'smtp.yandex.ru';
$mail->SMTPAuth = true;
$mail->Username = 'user@yandex.ru';
$mail->Password = 'пароль_приложения';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
$mail->CharSet = 'UTF-8';
$mail->setFrom('user@yandex.ru', 'Отправитель');
$mail->addAddress('recipient@example.com');
$mail->Subject = 'Тема письма';
$mail->Body = '<h1>Привет!</h1><p>Это HTML-письмо.</p>';
$mail->isHTML(true);
if (!$mail->send()) {
echo 'Ошибка: ' . $mail->ErrorInfo;
} else {
echo 'Письмо отправлено';
}

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

Цель использования

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

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

Встроенная функция mail() доступна в любой конфигурации PHP, но она не использует SMTP и полагается на системный почтовый сервер (sendmail). Решение подходит для локальной разработки или простых уведомлений.

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

отправить почту php (отправка почты в php)

Типичная проблема: письмо уходит в спам или не доходит

Функция mail() не указывает правильные заголовки DKIM и SPF, поэтому многие почтовые сервисы блокируют такие письма. На сервере может отсутствовать sendmail, и письма теряются.

Как решить

Использовать библиотеки с SMTP-аутентификацией (PHPMailer, Symfony Mailer). Если необходимо оставить mail(), настроить sendmail и добавить SPF-запись в DNS.

Как отправить письмо через SMTP с помощью потока (stream context)?

Можно напрямую соединиться с SMTP-сервером через сокеты, используя stream_context_create. Этот метод требует ручной реализации протокола.

$smtpServer = 'smtp.example.com';
$port = 587;
$username = 'user@example.com';
$password = 'password';
$from = 'user@example.com';
$to = 'recipient@example.com';
$subject = 'Тест SMTP';
$body = 'Привет!';

$context = stream_context_create([
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false
]
]);
$socket = fsockopen($smtpServer, $port, $errno, $errstr, 30);
if (!$socket) die("Не удалось соединиться: $errstr ($errno)");
stream_set_blocking($socket, true);
fgets($socket, 512);
fwrite($socket, "EHLO client\r\n");
fgets($socket, 512);
fwrite($socket, "AUTH LOGIN\r\n");
fgets($socket, 512);
fwrite($socket, base64_encode($username) . "\r\n");
fgets($socket, 512);
fwrite($socket, base64_encode($password) . "\r\n");
fgets($socket, 512);
fwrite($socket, "MAIL FROM:<$from>\r\n");
fgets($socket, 512);
fwrite($socket, "RCPT TO:<$to>\r\n");
fgets($socket, 512);
fwrite($socket, "DATA\r\n");
fgets($socket, 512);
fwrite($socket, "Subject: $subject\r\n");
fwrite($socket, "From: $from\r\n");
fwrite($socket, "Content-Type: text/plain; charset=UTF-8\r\n");
fwrite($socket, "\r\n$body\r\n.\r\n");
fgets($socket, 512);
fwrite($socket, "QUIT\r\n");
fclose($socket);

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

Проблема: сложность реализации и отсутствие обработки ошибок

Код громоздкий, сложно поддерживать, не учитывает шифрование, ответы сервера могут быть разными. Такой подход используется только в учебных целях.

Как отправить email через библиотеку SwiftMailer (устаревшая)?

SwiftMailer ранее был популярен, но его заменили PHPMailer и Symfony Mailer. Для старых проектов код выглядит так:

require_once 'swift_required.php';
$transport = Swift_SmtpTransport::newInstance('smtp.example.com', 587)
->setUsername('user')
->setPassword('pass');
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance('Тема')
->setFrom(['user@example.com' => 'Отправитель'])
->setTo(['recipient@example.com'])
->setBody('Привет!', 'text/plain');
$result = $mailer->send($message);

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

Проблема: прекращение поддержки и сложная установка

SwiftMailer не обновляется с 2017 года. Для новых проектов рекомендуется использовать PHPMailer или Symfony Mailer.

Как отправить почту с помощью Symfony Mailer (современный стандарт)?

Symfony Mailer – часть Symfony, но может использоваться отдельно. Устанавливается через Composer:

composer require symfony/mailer symfony/mime

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

Пример настройки SMTP Gmail:

use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mime\Email;

$transport = Transport::fromDsn('smtp://user%40gmail.com:password@smtp.gmail.com:587?encryption=tls');
$mailer = new Mailer($transport);
$email = (new Email())
->from('user@gmail.com')
->to('recipient@example.com')
->subject('Тест Symfony Mailer')
->text('Текст')
->html('<h1>HTML</h1>');
$mailer->send($email);

Проблема: зависимость от Symfony компонентов

Требуется PHP 7.4+ и установка дополнительных библиотек. В маленьких проектах проще использовать PHPMailer.

Расширенные примеры отправки почты

Пример
<?php
// Пример 1: PHPMailer с вложением и отладочным выводом
require 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.mail.ru';
$mail->SMTPAuth = true;
$mail->Username = 'user@mail.ru';
$mail->Password = 'пароль';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->CharSet = 'UTF-8';
$mail->SMTPDebug = 2; // вывод отладочной информации
$mail->setFrom('user@mail.ru', 'Отправитель');
$mail->addAddress('client@example.com', 'Клиент');
$mail->addReplyTo('support@mail.ru', 'Поддержка');
$mail->addAttachment('/path/to/file.pdf', 'документ.pdf');
$mail->isHTML(true);
$mail->Subject = 'Заказ №123';
$mail->Body = '<b>Спасибо за заказ!</b> Детали во вложении.';
$mail->AltBody = 'Спасибо за заказ! Детали во вложении.';
$mail->send();
echo 'Письмо отправлено';
} catch (Exception $e) {
echo "Ошибка: {$mail->ErrorInfo}";
}
Письмо отправлено (успех) или Ошибка: SMTP connect() failed. (если проблема с соединением)

Пример
<?php
// Пример 2: Отправка массовой рассылки через Symfony Mailer с использованием очереди
use Symfony\Component\Mailer\Transport\SendmailTransport;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mime\Email;
$transport = new SendmailTransport();
$mailer = new Mailer($transport);
$emails = [
['to' => 'user1@example.com', 'name' => 'User1'],
['to' => 'user2@example.com', 'name' => 'User2']
];
foreach ($emails as $recipient) {
$email = (new Email())
->from('newsletter@example.com')
->to($recipient['to'])
->subject('Новости')
->text('Привет, ' . $recipient['name'] . '!');
$mailer->send($email);
}
echo 'Рассылка завершена';
Рассылка завершена

Пример
<?php
// Пример 3: Использование mail() с дополнительными заголовками для борьбы со спамом
$to = 'recipient@example.com';
$subject = '=?UTF-8?B?' . base64_encode('Важное сообщение') . '?=';
$message = wordwrap('Текст письма, которое не должно разрываться на длинные строки.', 70, "\r\n");
$headers = implode("\r\n", [
'MIME-Version: 1.0',
'Content-type: text/plain; charset=UTF-8',
'From: =?UTF-8?B?' . base64_encode('Отправитель') . '?= ',
'Reply-To: noreply@example.com',
'X-Mailer: PHP/' . phpversion(),
'List-Unsubscribe: ',
]);
if (mail($to, $subject, $message, $headers)) {
echo 'Письмо отправлено';
} else {
echo 'Ошибка';
}
Письмо отправлено (если sendmail работает)

Пример
<?php
// Пример 4: Проверка существования почтового ящика через SMTP (VRFY команда)
$socket = fsockopen('mx.example.com', 25, $errno, $errstr, 10);
if ($socket) {
fgets($socket, 256);
fwrite($socket, "EHLO checker\r\n");
fgets($socket, 256);
fwrite($socket, "VRFY user@example.com\r\n");
$response = fgets($socket, 256);
fwrite($socket, "QUIT\r\n");
fclose($socket);
if (strpos($response, '250') === 0) {
echo 'Ящик существует';
} else {
echo 'Ящик не найден';
}
} else {
echo 'Не удалось соединиться';
}
Ящик существует (или не найден)

Отправка email через PHP - comments

En
Mail php p (php)