WordPress "инициализация phpmailer" не работает для меня


Я добавляю следующий код в файл functions.php.

add_action( 'phpmailer_init', 'my_phpmailer_example' );
function my_phpmailer_example( $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;
}

И wp-config.php

// SMTP email settings
define( 'SMTP_USER', '{email}' );
define( 'SMTP_PASS', '{password}' );
define( 'SMTP_HOST', '{server}' );
define( 'SMTP_FROM', '{from}' );
define( 'SMTP_NAME', '{name}' );
define( 'SMTP_PORT', '465' );
define( 'SMTP_SECURE', 'ssl' );
define( 'SMTP_AUTH', true );

"wp-login.php?action=lostpassword" когда я захожу сюда, я ввожу свой адрес электронной почты и нажимаю кнопку отправить,

enter image description here

" Не удалось отправить электронное письмо. Возможно, ваш сайт неправильно настроен для отправки электронной почты". Я получаю эту ошибку.


Но когда я вставляю тот же код в другой WordPress с установленным плагином WooCommerce, Я забыл свой WooCommerce пароль. Почта может быть успешно отправлена из внешнего интерфейса.

В чем проблема? Я делаю что-то не так?


3-й шаг

add_action( 'wp_mail_failed', function ( $error ) {
    error_log( $error->get_error_message() );
} );

Не работает (IDK). Но я поискал и нашел код ниже,

add_action('wp_mail_failed', 'log_mailer_errors', 10, 1);
function log_mailer_errors( $wp_error ){
  $fn = ABSPATH . '/mail.log'; // say you've got a mail.log file in your server root
  $fp = fopen($fn, 'a');
  fputs($fp, "Mailer Error: " . $wp_error->get_error_message() ."\n");
  fclose($fp);
}

Это дало мне следующую ошибку

Mailer Error: Invalid address:  (From): wordpress@localhost

Я нашел соответствующее местоположение из pluggable.php.

Так как я работал на localhost, он выдавал недопустимый адрес электронной почты, потому что он не создавал действительный ДВУ.

        if ( ! isset( $from_email ) ) {
            // Get the site domain and get rid of www.
            $sitename = wp_parse_url( network_home_url(), PHP_URL_HOST );
            if ( 'www.' === substr( $sitename, 0, 4 ) ) {
                $sitename = substr( $sitename, 4 );
            }

            $from_email = 'wordpress@' . $sitename;
        }

Это означает, что следует использовать "$phpmailer->From = SMTP_FROM;" вместо "add_filter ('wp_mail_from', 'set_from');".

function set_from()
{
    return '[email protected]';
}

add_filter('wp_mail_from', 'set_from');

Теперь работает.

Я не понимаю, почему phpmailer_init не перезаписывает из информации.


Кстати, отправитель по-прежнему выглядит так, как я определил в ($phpmailer-> From).

Я предполагаю, что это какая-то ошибка, и о ней следует сообщить в WordPress?

Author: km onur, 2021-02-03

1 answers

В чем проблема? Я делаю что-то не так?

Ваш код кажется мне нормальным, поэтому, несмотря на то, что я не могу дать вам окончательного ответа о том, в чем/где именно заключается проблема, я подумал, что это может помочь вам устранить проблему:

  1. Прежде всего, проверьте свою конфигурацию - например, использовали ли вы правильное (SMTP) имя пользователя/адрес электронной почты, пароль, хост?

    И убедитесь, что значение SMTP_FROM является допустимым адреса электронной почты - например, [email protected] и нет user@example или User <[email protected]>; в противном случае электронное письмо не будет отправлено.

  2. Если вы уверены, что конфигурация хорошая, то, поскольку вы используете SMTP, попробуйте включить отладку таким образом - добавьте это в свою функцию my_phpmailer_example():

    // Note: I assumed you're using at least WordPress version 5.5.0
    
    $phpmailer->SMTPDebug = PHPMailer\PHPMailer\SMTP::DEBUG_SERVER;
    

    Затем посетите страницу сброса пароля WordPress и попробуйте сбросить свой пароль, а на следующей странице, если PHPMailer не смог отправить электронное письмо, вы увидите сообщение об ошибке, отображаемое в верхней части страницы.

  3. Если вы не могу выполнить отладку SMTP выше (на самом деле это просто быстрое устранение неполадок), затем включите отладку в WordPress и используйте wp_mail_failed крюк чтобы попытаться поймать любые ошибки при отправке электронного письма - добавьте это в файл функций:

    add_action( 'wp_mail_failed', function ( $error ) {
        error_log( $error->get_error_message() );
    } );
    

    Затем проверьте файл wp-content/debug.log и посмотрите, есть ли какие-либо соответствующие ошибки/информация.

Обновление

(извините, я не мог удержаться, чтобы не сказать это) Мне понравился этот вопрос, и я рад, что вам удалось исправить вопрос. :)

Я предполагаю, что это какая-то ошибка, и о ней следует сообщить в WordPress?

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

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

Так как я работал на локальном хостинге, это отправлял недопустимый адрес электронной почты , потому что он не создавал действительный TLD.

Да, и я догадался, что вы уже видели эту заметку в wp_mail() код (в pluggable.php):

/*
 * If we don't have an email from the input headers, default to wordpress@$sitename
 * Some hosts will block outgoing mail from this address if it doesn't exist,
 * but there's no easy alternative. Defaulting to admin_email might appear to be
 * another option, but some hosts may refuse to relay mail from an unknown domain.
 * See https://core.trac.wordpress.org/ticket/5007.
 */

Так что да, либо используйте wp_mail_from крюк или, как я сказал выше, используйте виртуальный хост.

Я не понимаю, почему phpmailer_init не перезаписывает из информации.

Потому что WordPress/wp_mail() звонки $phpmailer->setFrom() чтобы установить From свойство и если PHPMailer выдает исключение/ошибку (например, из-за неверного адреса электронной почты), то wp_mail() возвращает false и никогда не запускает phpmailer_init крючок.

Но wp_mail_failedкрючок срабатывает, поэтому это очень хороший способ поймать любые ошибки, которые могут возникнуть при отправке электронного письма с использованием wp_mail(). ( и извините, я не упомянул об этом ранее, потому что я думал, что отладка SMTP будет работать и для вас :) )

Кстати, отправитель все еще кажется тем, что я определил в ($phpmailer->From).

Да, это нормально, потому что setFrom() вызывается до срабатывания крючка phpmailer_init.

И на самом деле, когда я сказал "включить отладку в WordPress", я имел в виду установить константы WP_DEBUG и WP_DEBUG_LOG в true; и если error_log() не записывается в wp-content/debug.log (или файл, определенный с помощью константы WP_DEBUG_LOG), то вы можете использовать 2-й и 3-й параметры для error_log() примерно так:

add_action( 'wp_mail_failed', function ( $error ) {
    // the "3" means write the message to the file as defined in the third parameter
    error_log( $error->get_error_message(), 3, WP_CONTENT_DIR . '/debug.log' );
} );

Но в любом случае, я надеюсь, что этот ответ/обновление и этот вопрос также поможет кому-то другому. =) Счастливого кодирования!

 0
Author: Sally CJ, 2021-02-04 15:05:52