Как программно настроить SMTP

13 дек. 2012 г., 10:48:08
Просмотры: 55.1K
Голосов: 23

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

0
Все ответы на вопрос 3
12
36

Прежде всего, если мы посмотрим на реализацию функции wp_mail, то увидим, что она использует класс PHPMailer для отправки электронных писем. Также можно заметить жестко прописанный вызов функции $phpmailer->IsMail();, который указывает использовать PHP-функцию mail(). Это означает, что мы не можем использовать настройки SMTP с этим вызовом. Нам нужно вызвать функцию isSMTP класса PHPMailer. И также нам необходимо установить наши SMTP-настройки.

Для этого нам нужно получить доступ к переменной $phpmailer. И здесь мы обращаемся к действию phpmailer_init, которое вызывается перед отправкой письма. Таким образом, мы можем сделать то, что нам нужно, написав наш обработчик действия:

add_action( 'phpmailer_init', 'wpse8170_phpmailer_init' );
function wpse8170_phpmailer_init( PHPMailer $phpmailer ) {
    $phpmailer->Host = 'your.smtp.server.here'; // ваш SMTP-сервер
    $phpmailer->Port = 25; // может быть другим
    $phpmailer->Username = 'your_username@example.com'; // если требуется
    $phpmailer->Password = 'yourpassword'; // если требуется
    $phpmailer->SMTPAuth = true; // если требуется
    // $phpmailer->SMTPSecure = 'ssl'; // включить, если требуется, 'tls' - другое возможное значение

    $phpmailer->IsSMTP();
}

И это всё.

13 дек. 2012 г. 10:48:08
Комментарии

Отличная работа, Eugene, спасибо! Полагаю, эти 10 строк кода могут заменить целый SMTP-плагин...(?)

brasofilo brasofilo
13 дек. 2012 г. 13:59:42

@brasofilo спасибо! Думаю, это не может заменить SMTP-плагин, потому что плагин позволяет настраивать параметры в админ-панели. Этот сниппет — просто лучшая практика о том, "как изменить настройки email программно", без изменения файлов ядра или переопределения функции wp_mail.

Eugene Manuilov Eugene Manuilov
13 дек. 2012 г. 14:40:07

Может быть, ссылка на ядро? Только что обнаружил, что для SSL нужно использовать это: $phpmailer->SMTPSecure = 'ssl';, или 'tls', если это необходимо. ::: Еще раз: отличная работа!

brasofilo brasofilo
15 янв. 2013 г. 12:24:45

@brasofilo да, согласен. Не стесняйтесь редактировать ответ, если хотите. Спасибо за помощь.

Eugene Manuilov Eugene Manuilov
15 янв. 2013 г. 13:14:19

Куда следует поместить этот код? Я хочу, чтобы все мои темы использовали одни и те же SMTP-серверы.

Anjan Anjan
10 янв. 2014 г. 16:43:23

@Anjan создайте собственный плагин.

Eugene Manuilov Eugene Manuilov
10 янв. 2014 г. 17:49:10

Очень странно, что WordPress не делает это проще, ведь казалось бы, это распространённая задача — изменять подобное.

Carson Reinke Carson Reinke
30 апр. 2015 г. 16:14:49

Кажется, это больше не работает.

Etienne Dupuis Etienne Dupuis
2 нояб. 2015 г. 18:56:21

Кто-нибудь может подтвердить, что это всё ещё работает?

Jack Jack
9 нояб. 2015 г. 13:51:22

У меня это работает, @JackNicholson, тебе тоже стоит проверить на своей стороне.

Eugene Manuilov Eugene Manuilov
9 нояб. 2015 г. 16:41:18

Я использовал этот код, но WordPress отправляет через php mail(). Как заставить WordPress отправлять только через SMTP? Когда я использую wp_mail("hossein@hashemiui.com", "test", "test"); он не отправляет через SMTP

Hossein Hashemi Hossein Hashemi
28 янв. 2017 г. 01:55:48

В WordPress 5.5 используется новая версия PHPMailer. Приведённый выше код вызовет ошибку. Замените PHPMailer $phpmailer на \PHPMailer\PHPMailer\PHPMailer $phpmailer, и всё снова заработает!

Betty Betty
11 июн. 2021 г. 11:36:46
Показать остальные 7 комментариев
0
11

Дополнение к ответу @EugeneManuilov.

Настройки SMTP

По умолчанию их можно установить - как уже ответил @EugeneManuilov - только через колбэк, прикреплённый к do_action_ref_array(). Источник/ядро.

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) PHPMailer SMTP Settings
 * Description: Включает SMTP серверы, SSL/TSL аутентификацию и настройки SMTP.
 */

add_action( 'phpmailer_init', 'phpmailerSMTP' );
function phpmailerSMTP( $phpmailer )
{
    # $phpmailer->IsSMTP();
    # $phpmailer->SMTPAuth   = true;  // Аутентификация
    # $phpmailer->Host       = '';
    # $phpmailer->Username   = '';
    # $phpmailer->Password   = '';
    # $phpmailer->SMTPSecure = 'ssl'; // Включить если требуется - 'tls' другое возможное значение
    # $phpmailer->Port       = 26;    // SMTP порт - 26 для GMail
}

Исключения SMTP

По умолчанию WordPress не выводит отладочную информацию. Вместо этого он просто возвращает FALSE при возникновении ошибки. Вот небольшой плагин для исправления этого:

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) PHPMailer Exceptions & SMTP
 * Description: WordPress по умолчанию возвращает <code>FALSE</code> вместо <code>Exception</code>. Этот плагин исправляет это.
 */

add_action( 'phpmailer_init', 'WCMphpmailerException' );
function WCMphpmailerException( $phpmailer )
{
    if ( ! defined( 'WP_DEBUG' ) OR ! WP_DEBUG )
    {
        $phpmailer->SMTPDebug = 0;
        $phpmailer->debug = 0;
        return;
    }
    if ( ! current_user_can( 'manage_options' ) )
        return;

    // Включить SMTP
    # $phpmailer->IsSMTP();
    $phpmailer->SMTPDebug = 2;
    $phpmailer->debug     = 1;

    // Используйте `var_dump( $data )` для проверки данных в последний момент и
    // посмотреть, были ли изменения в ядре. Стоит также выводить данные во время
    // фильтра `wp_mail`, чтобы получить исходное состояние для сравнения.
    $data = apply_filters(
        'wp_mail',
        compact( 'to', 'subject', 'message', 'headers', 'attachments' )
    );

    current_user_can( 'manage_options' )
        AND print htmlspecialchars( var_export( $phpmailer, true ) );

    $error = null;
    try
    {
        $sent = $phpmailer->Send();
        ! $sent AND $error = new WP_Error( 'phpmailerError', $sent->ErrorInfo );
    }
    catch ( phpmailerException $e )
    {
        $error = new WP_Error( 'phpmailerException', $e->errorMessage() );
    }
    catch ( Exception $e )
    {
        $error = new WP_Error( 'defaultException', $e->getMessage() );
    }

    if ( is_wp_error( $error ) )
        return printf(
            "%s: %s",
            $error->get_error_code(),
            $error->get_error_message()
        );
}

Репозиторий

Оба плагина доступны в этом Gist на GitHub, поэтому проверяйте их там, чтобы получать обновления.

22 июн. 2013 г. 13:17:17
2

Другие ответы на этот пост, хотя и предлагают рабочее решение, не затрагивают проблему безопасности хранения учетных данных SMTP в файле плагина или functions.php. В некоторых случаях это может быть допустимо, но лучшие практики рекомендуют хранить эту информацию более безопасным способом. Нет веских причин не следовать лучшим практикам, когда речь идет о защите ваших учетных данных.

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

Лучший способ сделать это — определить константы для информации phpmailer в файле wp-config.php. Это уже обсуждалось как функция в компоненте Mail, но пока не было принято в качестве официального улучшения. Однако вы можете сделать это самостоятельно, добавив следующее в wp-config.php:

/**
 * Установите следующие константы в wp-config.php
 * Их следует добавить где-нибудь ДО
 * определения константы ABSPATH.
 */
define( 'SMTP_USER',   'user@example.com' );    // Имя пользователя для аутентификации SMTP
define( 'SMTP_PASS',   'smtp password' );       // Пароль для аутентификации SMTP
define( 'SMTP_HOST',   'smtp.example.com' );    // Имя хоста почтового сервера
define( 'SMTP_FROM',   'website@example.com' ); // Адрес отправителя SMTP
define( 'SMTP_NAME',   'e.g Website Name' );    // Имя отправителя SMTP
define( 'SMTP_PORT',   '25' );                  // Номер порта SMTP — вероятно, 25, 465 или 587
define( 'SMTP_SECURE', 'tls' );                 // Используемая система шифрования — ssl или tls
define( 'SMTP_AUTH',    true );                 // Использовать аутентификацию SMTP (true|false)
define( 'SMTP_DEBUG',   0 );                    // Только для отладки: установите 1 или 2

После того как эти константы определены в wp-config.php, их можно использовать где угодно, обращаясь к определенным константам. Таким образом, вы можете использовать их в файле плагина или в functions.php. (Для конкретного вопроса автора лучше использовать файл плагина.)

/**
 * Эта функция подключит wp_mail к аутентифицированному
 * SMTP-серверу. Значения берутся из констант, определенных в wp-config.php
 */
add_action( 'phpmailer_init', 'send_smtp_email' );
function send_smtp_email( $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;
}

Подробнее об этом можно узнать в этом посте и в гисте на GitHub здесь.

10 авг. 2017 г. 18:57:05
Комментарии

Действительно хорошее решение!

Phill Healey Phill Healey
8 сент. 2017 г. 21:14:04

Небольшое дополнение: Само собой разумеется, не храните учетные данные в системе контроля версий. Вместо этого используйте файл .env, добавленный в .gitignore. Впрочем, те, кто помещают что-то важное в wp-config.php, скорее всего вообще не используют контроль версий...

jsphpl jsphpl
29 авг. 2018 г. 18:32:52