Верх страницы
Обложка к записи Настройка отправки почты в WordPress через SMTP без плагинов
Время для прочтения: 0 мин. 49 сек.

Настройка отправки почты в WordPress через SMTP без плагинов

С ростом вашего проекта растёт количество отправляемых сайтом писем (оповещения пользователям, регистрации, блокировки) и всё больше из них ничанают попадать в спам или не доходить до адресата совсем, так как по умолчанию WordPress отправляет письма через стандартный системный траспорт.

Выход в данной ситуации — отправка писем через SMTP с авторизацией. И нет смысла ставить плагины, всё решается в несколько строк кода в конфиге вашего сайта.

В wp-config.php разместите данные константы перед определением ABSPATH и замените тестовые данные реквизитами своего SMTP сервера (yandex, google или любой другой):

<?php
// Имя пользователя для SMTP авторизации
define( 'SMTP_USER', 'user@example.com' );  
 
// Пароль пользователя для SMTP авторизации
define( 'SMTP_PASS', 'smtp password' );
 
// Хост почтового сервера
define( 'SMTP_HOST', 'smtp.example.com' );
 
// Обратный Email
define( 'SMTP_FROM', 'website@example.com' );
 
// Имя для обратного мыла
define( 'SMTP_NAME', 'Вася Пупкин' );
 
// Номер порта (25, 465, 587)
define( 'SMTP_PORT', '25' );
 
// Тип шифиования (ssl или tls)
define( 'SMTP_SECURE', 'tls' );
 
// Включение/отключение шифрования
define( 'SMTP_AUTH', true );
 
// Режим отладки (0, 1, 2)
define( 'SMTP_DEBUG', 0 );

В functions.php фильтруем стандартные параметры PHPMailer, передавая в него данные из констант, определённых в конфиге:

<?php
use PHPMailer\PHPMailer\PHPMailer;

/**
 * Настройка SMTP
 *
 * @param PHPMailer $phpmailer объект мэилера
 */
function mihdan_send_smtp_email( PHPMailer $phpmailer ) {
  $phpmailer->isSMTP();
  $phpmailer->Host       = SMTP_HOST;
  $phpmailer->SMTPAuth   = SMTP_AUTH;
  $phpmailer->Port       = SMTP_PORT;
  $phpmailer->Username   = SMTP_USER;
  $phpmailer->Password   = SMTP_PASS;
  $phpmailer->SMTPSecure = SMTP_SECURE;
  $phpmailer->From       = SMTP_FROM;
  $phpmailer->FromName   = SMTP_NAME;
}
add_action( 'phpmailer_init', 'mihdan_send_smtp_email' );

Проверка отправки

В корне сайта создайте файл mail.php со следующим содержимым и откройте его через браузер:

<?php
// Кому отправляем
$to = 'you@yourdomain.com';
  
// Тема письма
$subject = 'Проверка wp_mail';
 
// Само сообщение
$message = 'Это тестовое сообщение';
  
// Загружаем только ядро WordPress
define( 'WP_USE_THEMES', false );
require( 'wp-load.php' );
  
// Отправляем письмо
$sent_message = wp_mail( $to, $subject, $message );
 
if ( $sent_message ) {
    // Если сообщение успешно отправилось
    echo 'Всё чётко настроил, бро!';
} else {
    // Ошибки при отправке
    echo 'Где-то ты лоханулся знатно!';
}

Автор: Кобзарёв Михаил

Русский разработчик со стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Joomla, Drupal, Opencart, Laravel, Moonshine.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

66 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Dima Minka
5 лет назад

Отличный пост, спасибо.
Очень часто люди встречаются с проблемой доставки почти с WordPress or Woocommerce. А здесь все описано почему письма не приходят и как с этим бороться.

Карина
Карина
5 лет назад

а как установить headers text/html, чтобы html в письме корректно отображался?

Кирилл
5 лет назад

Шикарно то как! Можно оказывается и вовсе обойтись без плагина. Спасибо!

Alexander
5 лет назад

Супер, все работает! спасибо большое!

Александр
Александр
5 лет назад

Здравствуйте, инструкция полезная.

Но, держать пароль от smtp в открытом виде не безопасно? При взломе злоумышленник получит еще и данные от почты для спама?

Можно ли как то пароль шифровать, хотя бы в md5?

И второй вопрос, думаю многим будет интересно, как можно сделать, чтобы вся почта, которая отправяляется через wordpress дублировалась в телеграм ботом?

Где прописываются настройки бота?

Если напишите инструкцию, буду благодарен, многим пригодится.

Александр
Александр
5 лет назад
Ответить на  Кобзарёв Михаил

Спасибо, Михаил за ответ и за плагин. (раньше как то долго искал под Contact Form такое решение, автор сделал нужную вещь и думаю востребованную).

Сейчас немного другая задача, не везде нужно ставить Contact Form (тяжелая форма), иногда проще отдельный шаблон под страницу контактов с простенькой формой.

И на выходе вся почта идет через отправку самого wordpress и вот как повесить отправку в телеграм не нашел. (нашел плагин, который все шлет, но думал, возможно, что и без плагина можно прикрутить оповещения).

Перечитал ваши статьи и многие решения у вас как раз без плагинов, кодом, решил поинтересоваться, может уже делали ранее.

Anvar
Anvar
4 лет назад

а где находится этот файл functions.php?

Klim
Klim
4 лет назад

Статья по-прежнему актуальна. Просто и эффективно. Спасибо.

Иван
Иван
3 лет назад

Здравствуйте! Работает прекрасно, но только на главной странице, на других страницах, по типу /price /about и тд не работает. Не подскажете, пожалуйста, как исправить?

Иван
Иван
3 лет назад
Ответить на  Кобзарёв Михаил

Да, аджакс. Но я разобрался, вставив и юрл полную ссылку. Спасибо большое!

Олег
Олег
3 лет назад

Здравствуйте! Ребята, спасибо за статью – всё работает супер!
Единственное я никак не могу добится того, чтобы мои письма отправлялись с различных почт, которые я задаю в параметре From.
У меня на сайте стоит плагин WPCF-7.
Суть в том, что когда заполняют одну форму – пользователь должен получить письмо от: MyTestName1 <info@my-domain.com>
Когда заполняют другую – письмо от MyTestName2 <order@my-domain.com>

Я уже пробовал и так:

$headers = array(
    ‘From: MyTestName2 <order@my-domain.com>’,
);
wp_mail( $to, $subject, $message, $headers );

и так:

add_filter( ‘wp_mail_from’, ‘custom_wp_mail_from’ );
function custom_wp_mail_from( $email_address ){
    return ‘order@my-domain.com’;
}

add_filter( ‘wp_mail_from_name’, ‘custom_wp_mail_from_name’ );
function custom_wp_mail_from_name( $email_from ){
    return ‘MyTestName2’;
}

НО все письма всё равно приходят от

$phpmailer->From = SMTP_FROM;
$phpmailer->FromName = SMTP_NAME;

Есть идеи, как это реализовать? Можно ли вообще переопределить From???

Олег
Олег
3 лет назад
Ответить на  Кобзарёв Михаил

Поделитесь? А то весь день голову ломаю — ничего придумать не могу 🙁

Олег
Олег
3 лет назад
Ответить на  Кобзарёв Михаил

На сколько я понимаю, хук phpmailer_init срабатывает в момент инициализации WP. К тому моменту, как я могу выполнять какие-либо проверки для определения с какой контактной формы было отправлено письмо — PHPMailer уже проинициализирован и я никак не могу до него достучаться и изменить его значения.

Если я ошибаюсь — приведите, пожалуйста, конкретный пример реализации. Потому что пока я всё ещё не могу переопределить значение From

Олег
Олег
3 лет назад
Ответить на  Кобзарёв Михаил

Спасибо! Именно этот вариант и помог!

Олег
Олег
3 лет назад
Ответить на  Кобзарёв Михаил

Михаил, подскажите какое есть решение для моей проблемы. Очень нуждаюсь в вашем ответе.

Александр
Александр
3 лет назад

А у меня не работает — вечное ожидание… Хоть и делал все как в инструкции.

Александр
Александр
3 лет назад
Ответить на  Кобзарёв Михаил

Всё заработало! Спасибо. Поменял порт smtp.yandex.ru на 587 (хотя в почтовом клиенте стоит 485 и в помощи по настройкам у них тоже 485 ).

Ошоплл
Ошоплл
3 лет назад

Я так понял wp_mail нужно вызвать в форме с которой нужно отправить данные, в атрибуте action?

Павел
Павел
3 лет назад

Здравствуйте! Спасибо за пост, очень помог, все сработало по инструкции с первого раза.

Однако после обновления wp и темы соскочило обратно на wpmailer. Форма письмо отправляет, но через встроенный мейлер.

Я добавил заново строки в wp-content/themes/my theme/fuctions.php (wp-config.php апдейт не затронул)

И теперь НЕ работает, форма письмо не отправляет. При проверке через mail.php пишет:

Fatal error: Uncaught TypeError: Argument 1 passed to mihdan_send_smtp_email() must be an instance of PHPMailer, instance of PHPMailer\PHPMailer\PHPMailer given, called in /home/site/mysite.com/www/wp-includes/class-wp-hook.php on line 287 and defined in /home/tvoyfilm/thinkandfilm.com/www/wp-content/themes/inspiro/functions.php:32 Stack trace: #0 /home/site/mysite.com/www/wp-includes/class-wp-hook.php(287): mihdan_send_smtp_email(Object(PHPMailer\PHPMailer\PHPMailer)) #1 /home/site/mysite.com/www/wp-includes/class-wp-hook.php(311): WP_Hook->apply_filters(NULL, Array) #2 /home/site/mysite.com/www/wp-includes/plugin.php(544): WP_Hook->do_action(Array) #3 /home/site/mysite.com/www/wp-includes/pluggable.php(494): do_action_ref_array('phpmailer_init', Array) #4 /home/site/mysite.com/www/mail.php(16): wp_mail(Array, 'wp_mail check', 'Test') #5 {main} thrown in <strong>/home/site/mysite.com/www/wp-content/themes/inspiro/functions.php</strong> on line <strong>32</strong></p><p>There has been a critical error on your website.</p><p>Подскажите пожалуйста, как победить.

Спасибо!

Максим
Максим
1 год назад

Не смог запустить. В итоге у меня два варианта:

  1. если оставляю в конфиге define( ‘SMTP_SECURE’, ‘tls’ ) то получаю 504 Gateway Time-out и на сервере в логе 2021/12/14 13:00:55 [error] 63923#63923: *5072341 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 83.149.46.100, server: online.makdart.com, request: «GET /mail.php HTTP/2.0», upstream: «http://127.0.0.1:8080/mail.php», host: «online.makdart.com»
  2. меняю на ssl. Тогда получаю «Где-то ты лоханулся знатно!».

Настройки портов, логина всё перепроверил многократно.

Максим
Максим
1 год назад
Ответить на  Кобзарёв Михаил

Разобрался, был не прав. Проблема была на стороне сервера, не настроен ssl и сертификат. Настроил и всё ок

Артём
Артём
1 год назад

Привет, я поставил PHPMailer на простой самописный одностаничник, без CMS.
Мне нужно принимать файлы от пользователя. 
На стороне формы у меня стоит ограничение:

<input type="file" accept=".png, .jpg, .jpeg, .pdf">

Но, если прикрепишь больше одного файла, то в почту придет последний прикрепленный.
Не могу этот момент отрегулировать.
В чем может быть дело?

Дмитрий
Дмитрий
1 год назад

Добрый день! У меня так и не вышло настроек. Где-то лоханулся.. но где, не ясно..
Вроде все ок
https://disk.yandex.ru/i/qZ_Z0kW55Zzbdg
https://disk.yandex.ru/i/gvFxs-e2UBKuog

Nadir
Nadir
1 год назад
Ответить на  Дмитрий

Поменяй ssl на tls и заработает

Андрей
Андрей
1 год назад

Добрый день! Не подскажите, что за данные и для чего они нужны?

// Обратный Email
define( 'SMTP_FROM', 'website@example.com'

);
  
// Имя для обратного мыла
define( 'SMTP_NAME', 'Вася Пупкин'

);

Последний раз редактировалось 1 год назад Андрей ем
Алексей
Алексей
1 год назад

Линк сюда дают в поддержке fozzy 😋

Сергей
Сергей
11 месяцев назад

В файле wp-config.php после добавления данных сразу появляется ошибка на первой же строке добавленных строк:
syntax error, unexpected ‘define’ (T_STRING)

Сергей
Сергей
11 месяцев назад
Ответить на  Кобзарёв Михаил

да, прям в начале файла сразу после тега. В случае с файлом wp-config.php проблема решилась удалением : на пустых строках, но такая же ошибка есть и в functions.php и тут никаких левых символов, но ругается на строку:
function mihdan_send_smtp_email( PHPMailer $phpmailer ) {

Сергей
Сергей
11 месяцев назад
Ответить на  Сергей

Странно, но при копировании из chrome ошибки нет, а вот из firefox есть. Как-то криво копируется

Иван Русский
Иван Русский
11 месяцев назад

Это лучшая статья, которую я читал по заданной теме. Порадовало множество комментариев и, главное, ответов на них автора, в течение СЕМИ лет. Михаил, Вам респект и Уважение!!! А у Вас есть ютуб канал, хочу посмотреть Ваши уроки.

Алексей
Алексей
10 месяцев назад

Спасибо за этот пост. То, что нужно. Не хочется лишний раз грузить систему дополнительными плагинами.

egor
egor
21 дней назад

не работает. просто повисает. возможно понятие открыть в браузере mail.php делаю не так. я просто в адресную строку добавил. после доменного имени

egor
egor
21 дней назад
Ответить на  egor

даже ошибку не выдает. просто висит.

egor
egor
21 дней назад
Ответить на  egor

все. работает. как обычно, опечатка, но странно что ошибка не вылетела. просто скрипт висел, крутил и все.

Дмитрий
Дмитрий
6 часов назад

Спасибо тебе, добрый программист!) Потестил, всё работает. Момент такой, что wp-config должен быть в кодировке UTF-8 иначе вместо имени отправителя будет ??????
Доволен, когда можно обойтись чистым кодом. Спасибо! 🙂

Предыдущая запись
Следующая запись

Давайте дружить
в Телеграме

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы