PHP-отправитель почты: от базовой функции до библиотек
Основные методы отправки почты в PHP
PHPMailer с SMTP - надежное решение
Как отправлять письма через внешний SMTP-сервер (Gmail, Яндекс) с полным контролем?
Библиотека PHPMailer позволяет отправлять письма через SMTP, поддерживает шифрование, вложения, HTML-верстку и автоматическую обработку заголовков. Это наиболее распространенный и стабильный способ.
Установка через Composer:
composer require phpmailer/phpmailerPhp mail (отправка почты в php)
Пример базового использования с SMTP Gmail:
require 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$mail = new PHPMailer(true);
try {
// Настройки SMTP
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->Username = 'your-email@gmail.com';
$mail->Password = 'your-app-password';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
// Отправитель и получатель
$mail->setFrom('from@example.com', 'Имя Отправителя');
$mail->addAddress('to@example.com', 'Имя Получателя');
// Контент
$mail->isHTML(true);
$mail->Subject = 'Тема письма';
$mail->Body = '<p>Это HTML-письмо</p>';
$mail->AltBody = 'Текстовая версия письма для клиентов без HTML';
$mail->send();
echo 'Письмо отправлено';
} catch (Exception $e) {
echo "Ошибка: {$mail->ErrorInfo}";
}Message php (отправка сообщений в php)
Типичные проблемы и решения
- Ошибка аутентификации: следует убедиться, что используется пароль приложения (для Gmail), а не обычный.
- Блокировка порта: провайдер может блокировать 25/587 - используйте порт 465 с SSL.
- Ошибки сертификата: требуется установить правильный путь к сертификату CA или отключить проверку (не рекомендуется).
Вариант 1. Встроенная функция mail()
Как отправить простое письмо без внешних библиотек?
Функция mail() использует локальный почтовый сервер (sendmail, postfix). Подходит для простых уведомлений, но часто попадает в спам и не поддерживает SMTP-аутентификацию.
$to = 'user@example.com';
$subject = 'Приветствие';
$message = 'Привет! Это тестовое письмо.';
$headers = 'From: webmaster@example.com' . "\r\n" .
'Reply-To: webmaster@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
if (mail($to, $subject, $message, $headers)) {
echo "Письмо отправлено";
} else {
echo "Ошибка отправки";
}
Mail php p (отправка email через php)
Типичные проблемы
- Письмо не доходит: без SMTP-аутентификации многие серверы блокируют письма. Настройка SPF/DKIM обязательна.
- Китайские символы: следует задать заголовок Content-Type с кодировкой UTF-8.
- Ошибка "Could not execute mail delivery program": не настроен sendmail на сервере.
Вариант 2. Отправка через почтовый API (SendGrid, Mailgun) с помощью cURL
Как интегрировать отправку писем через облачный сервис, чтобы повысить доставляемость?
Популярные сервисы (SendGrid, Mailgun, Amazon SES) предоставляют REST API. Пример отправки через SendGrid с помощью cURL:
$apiKey = 'YOUR_SENDGRID_API_KEY';
$data = [
'personalizations' => [
['to' => [['email' => 'recipient@example.com']]]
],
'from' => ['email' => 'from@example.com'],
'subject' => 'Привет от SendGrid',
'content' => [
['type' => 'text/plain', 'value' => 'Текст письма']
]
];
$ch = curl_init('https://api.sendgrid.com/v3/mail/send');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 202) {
echo "Письмо отправлено";
} else {
echo "Ошибка: $response";
}
Типичные проблемы
- API-ключ недействителен: необходимо проверить права ключа (может быть ограничен по IP).
- Превышение лимитов: бесплатные тарифы имеют ограничения на количество писем в день.
- Формат данных: неверный JSON приводит к ошибке 400.
Расширенные примеры отправки почты
Пример 1: PHPMailer с вложением и несколькими адресами
Добавляем файл из папки на сервере и отправляем копии:
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.mailtrap.io';
$mail->SMTPAuth = true;
$mail->Username = 'username';
$mail->Password = 'password';
$mail->Port = 2525;
$mail->SMTPSecure = 'tls';
// Отправитель
$mail->setFrom('sender@example.com', 'Sender');
// Основной получатель
$mail->addAddress('user1@example.com', 'Пользователь 1');
// Копия
$mail->addCC('user2@example.com', 'Пользователь 2');
// Скрытая копия
$mail->addBCC('admin@example.com');
// Вложение
$mail->addAttachment('/path/to/file.pdf', 'документ.pdf');
// Если файл из строки:
// $mail->addStringAttachment($pdfString, 'report.pdf');
$mail->Subject = 'Отчет за месяц';
$mail->Body = '<h1>Отчет</h1><p>См. вложение</p>';
$mail->AltBody = 'Отчет во вложении.';
$mail->send();
Письмо отправлено успешно.
Пример 2: PHPMailer с SSL (порт 465)
Использование шифрования SSL для серверов, не поддерживающих STARTTLS:
$mail->isSMTP();
$mail->Host = 'smtp.yandex.ru';
$mail->SMTPAuth = true;
$mail->Username = 'user@yandex.ru';
$mail->Password = 'app_password';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; // 'ssl'
$mail->Port = 465;
// Далее аналогично
Письмо отправлено.
Пример 3: PHPMailer с подробным логированием ошибок
Для отладки включим вывод SMTP-диалога:
$mail->SMTPDebug = 2; // 0 - выкл, 1 - ошибки, 2 - диалог
$mail->Debugoutput = function($str, $level) {
file_put_contents('phpmailer.log', $str, FILE_APPEND);
};
$mail->send();
Логи пишутся в файл phpmailer.log.
Пример 4: Функция mail() с HTML и альтернативным текстом (MIME)
Создаем multipart/alternative письмо с двумя версиями:
$boundary = '--==MIME_Boundary_' . md5(time());
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From: sender@example.com\r\n";
$headers .= "Content-Type: multipart/alternative; boundary=\"$boundary\"\r\n";
$plain = "Текстовая версия";
$html = "<h1>HTML версия</h1>";
$body = "--$boundary\r\n";
$body .= "Content-Type: text/plain; charset=utf-8\r\n\r\n";
$body .= $plain . "\r\n";
$body .= "--$boundary\r\n";
$body .= "Content-Type: text/html; charset=utf-8\r\n\r\n";
$body .= $html . "\r\n";
$body .= "--$boundary--";
mail('to@example.com', 'Тема', $body, $headers);
Письмо отправлено. Убедитесь, что сервер поддерживает MIME.
Пример 5: Функция mail() с вложением (base64)
Добавляем файл как вложение используя multipart/mixed:
$file = 'image.jpg';
$content = file_get_contents($file);
$encoded = chunk_split(base64_encode($content));
$boundary = '==boundary_' . md5(time());
$headers = "MIME-Version: 1.0\r\n";
$headers .= "From: sender@example.com\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
$body = "--$boundary\r\n";
$body .= "Content-Type: text/plain; charset=utf-8\r\n\r\n";
$body .= "Файл во вложении.\r\n";
$body .= "--$boundary\r\n";
$body .= "Content-Type: image/jpeg; name=\"image.jpg\"\r\n";
$body .= "Content-Disposition: attachment; filename=\"image.jpg\"\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n\r\n";
$body .= $encoded . "\r\n";
$body .= "--$boundary--";
mail('to@example.com', 'Вложение', $body, $headers);
Письмо отправлено с вложением.