WordPress отказывается отправлять почту, "...ваш хостинг мог отключить функцию mail()"

8 апр. 2013 г., 17:23:48
Просмотры: 98.5K
Голосов: 12

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

Чтобы проверить, может ли PHP отправлять письма, я попробовал сбросить пароль (так как новый пароль должен прийти по почте), и получил сообщение:

Письмо не может быть отправлено. Возможная причина: ваш хостинг мог отключить функцию mail()

Я проверил все галочки в Настройки -> Обсуждение, и email указан верно, так что проблема не в настройках. Я попробовал создать PHP файл и отправить письмо используя mail(), и оно успешно отправилось. Так что, должно быть, что-то странное происходит именно с WordPress.

Есть какие-нибудь идеи?

1
Комментарии

Пожалуйста, предоставьте информацию для отладки

s_ha_dum s_ha_dum
8 апр. 2013 г. 18:12:31
Все ответы на вопрос 10
5

Пошагово: сначала найдите файл, в котором появляется сообщение об ошибке. Я использую Notepad++ и команду CTRL + F для поиска по файлам. Хорошая идея — искать только первые несколько слов сообщения об ошибке, так как некоторые сообщения могут быть составными.

Ваше сообщение об ошибке появляется в файле wp-login.php и, к счастью, только там. Давайте разберёмся, почему может возникать эта ошибка.

if ( $message && !wp_mail($user_email, $title, $message) )

Здесь два условия. $message должен быть true (не пустой строкой, не false, не null и т. д.). И wp_mail() не должен возвращать false.

На строку выше есть фильтр $message = apply_filters('retrieve_password_message', $message, $key);, так что возможно, что плагин (или тема) использует этот фильтр и возвращает значение, которое не является true (пустая строка, false, null и т. д.).

Но гораздо проще проверить, работает ли wp_mail(). Напишите небольшой плагин для отправки тестового письма себе:

<?php
/**
 * Plugin Name: Stackexchange Testplugin
 * Plugin URI:  http://yoda.neun12.de
 * Description: Отправьте мне тестовое письмо
 * Version:     0.1
 * Author:      Ralf Albert
 * Author URI:  http://yoda.neun12.de
 * Text Domain:
 * Domain Path:
 * Network:
 * License:     GPLv3
 */

namespace WordPressStackexchange;

add_action( 'init', __NAMESPACE__ . '\plugin_init' );

function plugin_init(){
    $to      = 'ваш-email@ваш-домен.tld';
    $subject = 'Тестовое письмо';
    $message = 'FooBarBaz Тестовая почта работает';

    wp_mail( $to, $subject, $message );
}

(Это код для PHP5.3. Если у вас PHP5.2, удалите пространства имён.)

Плагин должен отправить тестовое письмо сразу после активации. Если нет, попробуйте открыть какую-нибудь страницу в админке (например, консоль).

Если тестовое письмо не приходит, скорее всего, у вас проблема с wp_mail(). Включите отладку:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', true );
@ini_set( 'display_errors',1 );

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

На этом этапе у вас будет достаточно информации, чтобы понять, работает ли wp_mail(), и если нет — почему. Если wp_mail() работает корректно и тестовое письмо пришло, вернитесь к началу и выясните, почему $message не является true.

Если у вас проблемы с wp_mail(), учтите, что wp_mail() не использует PHP-функцию mail(). WordPress использует PHP-класс (PHPMailer). Возможно, вам просто нужен плагин для использования SMTP вместо sendmail. Или проблема в другом месте. Мы не знаем. Вам придётся разбираться.

8 апр. 2013 г. 18:44:44
Комментарии

Да, я попытался разобраться в ядре, и это привело меня к PHPMailer, и он действительно использует php-функцию mail(). По крайней мере, в некоторых случаях (см. строку 732 в файле wp-includes/class-phpmailer.php. У меня сейчас нет доступа к FTP, но я попробую ваши предложения, как только смогу. Уверен, это должно привести меня к решению. Большое спасибо!

qwerty qwerty
8 апр. 2013 г. 20:52:27

Я протестировал wp_mail(), и, кажется, всё работает нормально — я получил письмо, как и ожидалось. Однако WordPress всё ещё не отправлял письма с комментариями/сбросом пароля, и в лог-файле ничего не появлялось (он даже не создавался). Поэтому я попробовал установить SMTP-плагин для почты и настроил новый почтовый аккаунт для WordPress. Теперь всё работает, но я всё равно не понимаю, почему раньше отправка не работала. Спасибо!

qwerty qwerty
9 апр. 2013 г. 10:05:52

Я не получаю никаких ошибок и даже самого письма

baldraider baldraider
19 авг. 2017 г. 10:29:36

Куда сохранять свой плагин?

Black Black
4 нояб. 2021 г. 11:19:11

Как видите, ответу около 8 лет. Я не работал с WordPress более 5 лет. Насколько я помню, в директории wp-plugins, как обычно. Но возможно за последние 5 лет что-то изменилось.

Ralf912 Ralf912
4 нояб. 2021 г. 15:30:13
0

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

Эта ошибка появляется, когда функция wp_mail() возвращает false, что в свою очередь может произойти, если phpmailer->Send() возвращает false или вызывает исключение.


Как отображать предупреждения от PHP-функции mail()

Они обычно подавляются по умолчанию, но, к сожалению, WordPress их никогда не перехватывает. Чтобы показать их, просто удалите знаки @ из строк @mail(... в файле wp-includes/class-phpmailer.php в функции mailPassthru():

if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
    $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header);
} else {
    $rt = @mail($to, $this->encodeHeader($this->secureHeader($subject)), $body, $header, $params);
}


Как выявить другие возможные причины:

  1. Добавьте одну строку в конец функции wp_mail() в файле /wp-includes/pluggable.php:

    // Отправка!
    try {
        return $phpmailer->Send();
    } catch ( phpmailerException $e ) {
        //------------- Эта следующая строка — та, которую нужно добавить -------------------
        if (WP_DEBUG) echo '<pre>' . esc_html(print_r($e, TRUE)) . '</pre>';
        return false;
    }
    
  2. Это выведет полные детали исключения, включая место, где оно было вызвано. К сожалению, иногда там содержится бесполезное сообщение: "Не удалось инициализировать почтовую функцию". Да, спасибо, WordPress, это действительно помогло.

  3. Изучив исключение, вы можете найти номер строки с ошибкой и, возможно, отследить её в коде, чтобы определить реальную причину.

Удачи. Надеюсь, в будущем WordPress улучшит обработку ошибок при отправке электронной почты.

11 дек. 2014 г. 02:08:19
1

У меня была такая же проблема с сервером Ubuntu на Amazon EC2. Я столкнулся с проблемой при использовании ссылки для сброса пароля, а также другие уведомления по электронной почте не работали.

Вот решение, которое сработало у меня. WordPress использует функцию wp_mail() для отправки почты, которой необходим класс PHPMailer, использующий почтовый сервер PHP, расположенный в /usr/sbin/sendmail.

Сначала используйте эту простую PHP-функцию, чтобы проверить работу почты в PHP:

<?php
$to = "example@gmail.com";
$subject = "Тестовая функция email";
$txt = "Привет, мир!";
$headers = "From: webmaster@example.com" . "\r\n" .
"CC: xyz@example.com";

mail($to,$subject,$txt,$headers);
?>

Если это не работает, то вам необходимо установить почтовый сервер PHP. Используйте эту команду для установки почтового сервера на сервер Ubuntu:

sudo apt-get install sendmail

Затем проверьте функции отправки email в WordPress.

3 мая 2017 г. 09:34:57
Комментарии

этот ответ должен быть первым, что попробует любой, прежде чем переходить к другим вариантам — это правильный путь

hatenine hatenine
25 янв. 2019 г. 14:53:34
0

Если другие отличные решения здесь не помогли, попробуйте следующее:

Я столкнулся с той же проблемой, и ни одно из предложенных решений для WordPress мне не помогло.

Затем я начал исследовать, не отключена ли функция mail в самой установке PHP, но и это не дало результатов. Все настройки казались правильными.

Все эти проблемы начались у меня после обновления сервера до CentOS 7, которая использует SELinux (Security Enhanced Linux). И то, что я понял за последние пару недель работы с SELinux - если что-то не работает, но все выглядит так, будто должно работать... это значит, что SELinux тихо и незаметно блокирует вас в фоновом режиме.

И вуаля.

Если вы используете операционную систему с SELinux, просто выполните следующую команду от имени root:

setsebool -P httpd_can_sendmail=1

Существует настройка безопасности, которая по умолчанию запрещает веб-серверу отправлять электронную почту. Когда вы меняете этот параметр и разрешаете SELinux отправку почты через веб-сервер, всё внезапно начинает работать.

4 февр. 2017 г. 21:24:09
0

Я столкнулся с этим сегодня; в моем случае проблема возникла из-за того, что в файле hosts сервера указано то же доменное имя, что и в адресе электронной почты, и оно направлено на localhost. MX-запись указывает на другой сервер, но файл hosts переопределяет DNS, и WordPress пытается доставить письмо локально. Удаление домена из файла hosts и перезапуск sendmail решили эту проблему.

16 янв. 2014 г. 21:15:23
0

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

Я столкнулся с точно такой же проблемой, когда мой хостинг на openshift внезапно перестал отправлять письма. Изучая код и документацию, я узнал о функции wp_mail(), а затем Google привёл меня сюда, где я увидел, как её можно переопределить.

Основываясь на ответе @Ralf912, я немного модифицировал скрипт, чтобы он использовал веб-API sendgrid.com для отправки писем вместо стандартного механизма WordPress (как я предполагаю):

<?php

function sendgridmail($to, $subject, $message, $headers)
{
    $url = 'https://api.sendgrid.com/';
    //$user = 'yourUsername';
    //$pass = 'yourPassword';

    $params = array(
        'api_user'  => $user,
        'api_key'   => $pass,
        'to'        => $to,
        'subject'   => $subject,
        'html'      => '',
        'text'      => $message,
        'from'      => 'abc@hotmail.com',
      );


    $request =  $url.'api/mail.send.json';

    // Генерируем curl-запрос
    $session = curl_init($request);
    // Указываем использовать POST
    curl_setopt ($session, CURLOPT_POST, true);
    // Указываем тело POST-запроса
    curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
    // Не возвращаем заголовки, но возвращаем ответ
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);

    // Получаем ответ
    $response = curl_exec($session);
    curl_close($session);

    // Выводим всё (раскомментируйте для отладки)
    //print_r($response);
}

// Только для тестирования:
/*$to      = 'abc@yahoo.com';
$subject = 'Testemail';
$message = 'It works!!';
echo 'To is: ' + $to;
#wp_mail( $to, $subject, $message, array() );
sendgridmail($to, $subject, $message, $headers);
print_r('Just sent!');*/

if (!function_exists('wp_mail')) {
    function wp_mail($to, $subject, $message, $headers = '', $attachments = array())
    {
        // Используем PHP GnuPG библиотеку для отправки почты
        sendgridmail($to, $subject, $message, $headers);
    }
}

function plugin_init()
{
   /* $to      = 'xyz@yahoo.com';
    $subject = 'Testemail';
    $message = 'It works Live!';
    //echo 'To is: ' + $to;
    wp_mail( $to, $subject, $message, array() );
    //print_r('Just sent!');*/
}

И это сработало!

30 мая 2014 г. 20:04:20
0

У меня была такая же ошибка - обе функции (mail и wp_mail) работали, но это надоедливое сообщение об ошибке не исчезало. Решение оказалось очень простым, но мне потребовалось несколько часов, чтобы найти причину. Поэтому я поделюсь здесь своим решением проблемы, которое может быть (или не быть) таким же, как у вас.

Я пробовал функцию mail(), и она работала, но при тестировании вы не указываете последний параметр под названием 'parameters' в функции mail(). А WordPress как раз его использует.

@mail("example@exmaple.com",$title,$body,$headers,"-fexample@exmaple.com");

По сути, этот параметр ("-fexample@exmaple.com") с флагом "-f" заставляет функцию mail() проверять, есть ли email-адрес "example@exmaple.com" в списке "доверенных email-адресов".

Если его там нет, функция возвращает false, что приводит к тому, что wp_mail() также возвращает false и вызывает сообщение об ошибке.

Решение - попросить хостинг-провайдера добавить email в доверенный список, либо, если вы используете cPanel, просто создать почтовый аккаунт для этого адреса, и он автоматически добавится в "доверенный список".

23 авг. 2016 г. 15:16:43
0

Это называется -Управление зарегистрированными email-адресами для отправки писем через скрипты, например (Wordpress)

  1. Войдите в вашу Cpanel.
  2. Перейдите в раздел Email > затем нажмите Registered Email IDs.
  3. Затем добавьте (wordpress@yourdomain.com) или где размещен ваш wordpress. Например (wordpress@blog.yourdomain.com). Затем подтвердите, это займет несколько минут для активации, подождите от 15 минут до 1 часа в зависимости от вашего хостинг-провайдера, после чего все заработает.
31 мая 2019 г. 20:03:57
0

Я долго мучился с этой ошибкой и перепробовал множество решений, которые не работали. У меня кастомная установка WordPress на AWS EC2. Прежде всего, убедитесь, что ваша почта AWS SES включена через поддержку, они должны быть в одном (или близком) регионе в SES и EC2.

Я использовал Google Suite (G Suite) для электронной почты, чтобы получать и отправлять письма.

Убедитесь, что тестовое письмо отправляется через AWS SES и G Suite.

Установите плагин WordPress WP Mail SMTP, выберите опцию "Другой SMTP", возьмите ваши SMTP-данные из AWS SES — именно здесь я застрял.

Вы должны включить галочку "SSL" для шифрования, это изменило порт на 465 у меня. Наконец, мое тестовое письмо успешно отправилось из WordPress.

14 дек. 2019 г. 17:16:51
0

Я исправил эту проблему, изменив "From Email" (Отправитель) в локальной тестовой среде, заменив wordpress@localhost на wordpress@localhost.localdomain, например, с помощью WordPress-плагина "WP Mail SMTP", выбрав стандартный PHP mailer вместо SMTP.

Проблема возникала даже при отключенных всех остальных плагинах, и ранее у меня не было этой проблемы. Также проблема отсутствует при использовании PHP-функции mail напрямую, так что, возможно, это связано с недавними изменениями в WordPress.

Я успешно отправлял и получал письма на локальном компьютере, используя Postfix.

26 февр. 2021 г. 14:14:59