Верх страницы
Обложка к записи Настройка отправки почты в 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 'Где-то ты лоханулся знатно!';
}

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

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

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

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

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

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

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

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

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

а как установить 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 лет назад

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

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

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

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

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

Олег
Олег
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>Подскажите пожалуйста, как победить.

Спасибо!

Максим
Максим
2 лет назад

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

  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. Тогда получаю «Где-то ты лоханулся знатно!».

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

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

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

Артём
Артём
2 лет назад

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

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

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

Дмитрий
Дмитрий
2 лет назад

Добрый день! У меня так и не вышло настроек. Где-то лоханулся.. но где, не ясно..
Вроде все ок
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 😋

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

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

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

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

Сергей
Сергей
1 год назад
Ответить на  Сергей

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

Иван Русский
Иван Русский
1 год назад

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

Алексей
Алексей
1 год назад

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

egor
egor
4 месяцев назад

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

egor
egor
4 месяцев назад
Ответить на  egor

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

egor
egor
4 месяцев назад
Ответить на  egor

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

Дмитрий
Дмитрий
3 месяцев назад

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

ТанЯ
ТанЯ
1 месяц назад

Спасибо!!!! Скажите, а можно ли обойтись без внесения изменений в файл config, прописав константы в functions?

ТанЯ
ТанЯ
23 дней назад

Все так хорошо работало, но потом что-то пошло не так…Теперь вечно крутит и ничего не происходит. Уже не знаю, что еще проверить

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

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

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