Почему wp_mail() не позволяет установить заголовок From:, когда обычная функция PHP mail() это позволяет?
Когда я использую wp_mail( $to, $subject, $message, $headers )
(с установленными значениями, конечно), письмо отправляется с именем отправителя и email, которые нигде не установлены (даже в настройках PHP или Apache). Однако, при использовании mail( $to, $subject, $message, $headers )
всё работает корректно. Что может происходить с wp_mail()
, что вызывает такое поведение?

Привет, @helenyhou:
Вы можете установить заголовок, просто не через параметр. WordPress использует "хуки", и нужные вам хуки — это 'wp_mail_from'
и 'wp_mail_from_name'
.
Вот хуки, которые вы можете добавить в файл functions.php
вашей темы, чтобы изменить заголовок "From:"
при использовании wp_mail()
на адрес Helen Hou-Sandi <helenyhou@example.com>
:
add_filter('wp_mail_from','yoursite_wp_mail_from');
function yoursite_wp_mail_from($content_type) {
return 'helenyhou@example.com';
}
add_filter('wp_mail_from_name','yoursite_wp_mail_from_name');
function yoursite_wp_mail_from_name($name) {
return 'Helen Hou-Sandi';
}

Я только что посмотрел фильтры, и вы правы, это действительно решает проблему. Полагаю, Кодекс следует обновить? http://codex.wordpress.org/Function_Reference/wp_mail
Также по теме: это затрагивает множество плагинов для форм, включая мощный GravityForms. Сейчас я пишу свою собственную форму, но если так должно работать в WP, почему установка заголовков старым добрым методом работает для других (и даже для некоторых моих других сайтов)?

@helenyhou - Чтобы не затронуть другие формы, вам нужно добавить фильтры в ваш плагин непосредственно перед вызовом wp_mail()
и затем удалить их сразу после. Что касается того, почему установка заголовков работает, я не знаю ваши другие случаи использования, но я был бы удивлен, если бы wp_mail()
работал именно так.

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

Обратите внимание, что любой фильтр, добавленный плагином, можно удалить с помощью remove_filter(HOК, FUNCTION).

Итак, если вы используете формат From: "Ваше Имя" <youremail@example.com>\r\n
в заголовках, у вас не должно быть проблем (если только у вас не установлен плагин, который переопределяет функцию wp_mail).
Однако, как сказал Майк, вы можете отфильтровать окончательные значения с помощью этих фильтров или просто установить этот плагин:
Он предоставит вам настройки для определения имени и email, используемых в wp_mail()
.

Извините, что поднимаю старый вопрос, но разве не лучше установить через заголовки вот так:
$subject = "MyPlugin: Оповещение (".get_bloginfo('wpurl').")";
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=".get_bloginfo('charset')."" . "\r\n";
$headers .= "From: MyPlugin <".$this->settings['from_address'].">" . "\r\n";
wp_mail($this->settings['notify_address'], $subject, $alertMessage, $headers);
Таким образом не нужно беспокоиться об использовании фильтра и его последующем удалении после wp_mail()
.

Я не устанавливал этот фильтр, это сделал другой плагин. Фильтр имеет приоритет над заголовком. Также вам действительно стоит использовать site_url()
вместо get_bloginfo('wpurl')

Но тогда, несомненно, этот плагин плохо себя ведет, не очищая за собой... Хотя с этим мало что можно поделать :( В таком случае мне лучше изменить свой плагин, чтобы использовать фильтры, на случай если другой плагин сломает его.

@helenyhou - +1 за напоминание о site_url(). Я тоже изменил свой плагин, чтобы использовать фильтры вместо $headers. Кроме того, я убедился, что удаляю эти фильтры после отправки письма, чтобы не мешать работе других плагинов :)

да, это недостаток того плагина, что он не даёт мне возможности не использовать эти фильтры, но, к счастью, их закомментирование сработало в моём случае. Я, наверное, поспрашиваю, что лучше использовать в будущем — фильтры для каждого использования или более привычные заголовки. Заголовки, вероятно, эффективнее, но тогда зачем нужны эти фильтры? Вопросов всегда больше :)

В текущей версии совершенно допустимо использовать get_bloginfo('wpurl')
: это уже возвращает site_url()
. get_bloginfo('home')
и get_bloginfo('siteurl')
устарели. https://developer.wordpress.org/reference/functions/get_bloginfo/

Это небольшой хак, но вы также можете использовать заголовок Reply To
:
$headers = 'Reply-To: "Aaren A. Aarenson" <aaron@somemail.com>';
К сожалению, это добавляет email-адрес в список From, и при ответе вам придется вручную удалять адрес, заданный в фильтре wp_mail_from
.

У меня была такая же проблема. Оказалось, что хостинг-провайдер (BlueHost) блокировал изменение поля from. Здесь они объясняют это https://my.bluehost.com/cgi/help/206.
Я решил проблему, добавив email в почтовые ящики cPanel, как они рекомендуют.
