Problem with PHP mail() and Additional Headers

With the PHP mail() function, you can specify additional headers for the emails that you send. This is a very powerful feature, which lets you do things such as add addresses to blind carbon copy or specify which email address the email is coming from.

It’s great but the PHP manual says this about additional headers: –

additional_headers (optional)

String to be inserted at the end of the email header.

This is typically used to add extra headers (From, Cc, and Bcc). Multiple extra headers should be separated with a CRLF (\r\n).

Yes, so according to the manual multiple headers should be separated with CRLF (\r\n). However, if you try this on a Linux web server (sample code provided below) you will probably get some of your headers stuck in the body of the email! There is a quick and easy solution though…

// Recipient
$to = '[email protected]';

// Subject of email
$subject = 'Message from Eddie';

// Message body
$message = 'Hi there, this is Eddie, and I\'m feeling just
great, guys, and I know I\'m just going to get a bundle of kicks out of any
programme you care to run through me';

// Additional headers
$headers = 'To: [email protected]' . "\r\n";
$headers .= 'From: [email protected]' . "\r\n";

// Mail it
if(mail($to, $subject, $message, $headers)) {
echo 'Email sent';
} else {
	echo 'Email not sent';
}

Apparently on Linux web servers, it’s best to use LF (\n) line endings for separating headers instead. This can be done two ways. The first way is to alter the server’s sendmail path in PHP.ini file to first push the email through dos2unix (which converts the line endings automatically) and then pipe it to send mail.

sendmail_path = "/usr/bin/dos2unix | /usr/sbin/sendmail -t -i"

The other option is to alter your PHP code so that instead of appending the line endings on as strings use the PHP_EOL constant which was introduced in PHP 5.0.2. Echoing PHP_EOL on a Windows server will result in “\r\n” whilst echoing the constant on a Linux server will result in “\n”… which in my opinion is a more elegant solution. :)