0

I've been having issues using wp_mail and mail functions in an application when specifying header elements in the function.

I usually set up the header as an associative array, as in

$mailheader = array(
                'MIME-Version' => '1.0',
                'Content-type' => ' text/html; charset=utf-8',
                'From' => '[email protected]'  ,
);

Using the mail() command, the headers are processed correctly, and the message is sent as an HTML mail.

mail("[email protected]", "my subject", "<p>A message here.</p>", $mailheader);

But if I use the same command with the wp_mail function (on a WP 6.x site), the message is sent as plain text:

wp_mail("[email protected]", "my subject", "<p>A message here.</p>", $mailheader);

If you want to use an associative array for the headers in wp_mail, you have to convert it text:

        foreach ($mailheader as $key => $value) {

            $header_wp .= "$key: $value \r\n";   // for wp-mail header which doesn't do arrays
     }

(Note the use of double quotes in the statement, so the \r\n is processed properly.)

And then use this wp_mail command:

wp_mail("[email protected]", "my subject", "<p>A message here.</p>", $header_wp );

This will result in an HTML-formatted message when using wp_mail.

I have verified this on different WP 6.01 sites with PHP versions 7.3 and 8.x. The processing of the header by wp_mail happens before it is sent to phpMailer.

I spent a couple of weeks fighting this one, so wanted to alert others.

I'll put the correct code in my answer to the question.

Added

I adjusted my question to emphasize that a two-dimensional header array will not work with wp_mail(), but will work with mail(). If you set up a two-dimensional array, you will need to convert to text string or a one-dimensional array (as noted in SallyCJ's answer).

** Added 2 **

Oops...got my term wrong. It is an associative array that does not work with wp_mail. See my example $mailheader associative array.

2 Answers 2

1

Both the mail() function in PHP and wp_mail() in WordPress do support passing an array or string of headers, but the difference is:

  • With mail(), the array keys are the header names and its values are the respective header values, e.g. array( 'Content-type' => 'text/html; charset=utf-8' ).

  • wp_mail() on the other hand, expects that the header name and value are put in the array values, e.g. array( 'Content-type: text/html; charset=utf-8' ).

So this statement is not necessarily true:

If you want to use an array for the headers in wp_mail, you have to convert it text

Because you could actually instead convert the format of your $mailheader array to:

$mailheader = array(
    'MIME-Version: 1.0',
    'Content-type: text/html; charset=utf-8',
    'From: [email protected]',
);

Or create a headers array specifically for wp_mail(), from that array, like so:

$headers = array();
foreach ( $mailheader as $key => $value ) {
    $headers[] = "$key: $value";
}

Example by Codex (see https://developer.wordpress.org/reference/functions/wp_mail/#comment-348):

To send HTML formatted mail, you also can specify the Content-Type HTTP header in the $headers parameter:

$to = '[email protected]';
$subject = 'The subject';
$body = 'The email body content';
$headers = array('Content-Type: text/html; charset=UTF-8');

wp_mail( $to, $subject, $body, $headers );

And the documentation also stated that:

  • $headers can be a string or an array, but it may be easiest to use in the array form.

  • When you are using the array form, you do not need to supply line breaks ("\n" or "\r\n").

    And thus, we could save time from trying to figure out whether CRLF (\r\n) or LF (\n) should be used..

5
  • I corrected/enhanced my original answer,to state that two-dimensional arrays (which was stated in the original question) do not work with wp_mail, but they will with mail(). The wp_mail function will only properly process a one-dimensional array, as shown in your answer. Commented Aug 6, 2022 at 21:44
  • You didn't make it clear in your original post that you were aware of the difference in the headers array format - if it was clear, I wouldn't bother to post an answer. And my answer was telling you and everyone else about 3 points: 1) The difference in the values between the array for mail() and wp_mail(). 2) It is not a must to convert your array to string - wouldn't it be much easier to just replace the ' => ' with : , i.e. change/correct the value's format? 3) With an array, we don't need to add \r\n or \n.
    – Sally CJ
    Commented Aug 6, 2022 at 22:45
  • And no, both the functions only accept one-dimensional array (e.g. array( 'I am 1D array') and array( 'yup' => 'me too 1D' )) and not two-dimensional array (i.e. an array of arrays) like array( array( 'nested' => 'array' ) ). But as stated in my answer, the array for mail() should use the header name as the key, whereas the array for wp_mail() should include the header name in the value - and the array is using numeric keys, but any keys supported by PHP would also work.
    – Sally CJ
    Commented Aug 6, 2022 at 22:47
  • Thanks for helping me correct the type of array to associative. The intent of my question and answer is to alert folks who are trying to use an associative array in wp_mail, which doesn't work. (And which I spent many hours trying to figure out. The limitation of wp_mails insistence on strings or wasn't clear in all my research - at least, how I groked the research results.) Commented Aug 7, 2022 at 20:38
  • Yes I was aware of that intent, so I posted my answer so that everyone including you and me know or be reminded that, "you have to convert it text" is not necessarily true. And also - always refer to the documentation, and check also the "User Contributed Notes" section, because that could save you from from those many hours. Also, I understand the "The associative array, which is allowed by the PHP mail() function, will not work with wp_mail()", but if I were you, I would add "because the array values are missing the header name". That's the main point that you should let others know.
    – Sally CJ
    Commented Aug 7, 2022 at 22:16
0

Added

Although wp_mail will accept a one-dimensional array, it will not accept a associative array, as in

$mailheader = array(
                'MIME-Version' => '1.0',
                'Content-type' => ' text/html; charset=utf-8',
                'From' => '[email protected]'  ,
);

The associative array, which is allowed by the PHP mail() function, will not work with wp_mail().

Original

To properly use headers in wp_mail, the header must be a string, not an array. Example code

    foreach ($mailheader as $key => $value) {

            $header_wp .= "$key: $value \r\n";   // for wp-mail header which doesn't do arrays
     }

(Note the use of double quotes in the statement, so the \r\n is processed properly.)

And then use this wp_mail command:

wp_mail("[email protected]", "my subject", "<p>A message here.</p>", $header_wp );

This will result in an HTML-formatted message when using wp_mail. If you use an array as the header in wp_mail, the message will be sent as plain text.

Correction used the wrong term for the type of array - it is associative, not two-dimensional. The associative array will not work in wp_mail.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.