phpemailphp-8.1

"--PHP-alt-" appearing in email body with php 8.1


I have upgraded to php 8.1 and now email sent with mail() is arriving with the following at the beginning of the body, where before it didn't:

--PHP-alt-4de4a7c8434ad5b8f6adb6e50c35b0da
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

The only difference I see in the header info is that each header line now has a space before it (lines 2-5 below):

X-PHP-Script: www.example.com/file.php for 0.0.0.0
 From: Name <name@example.com>
 Reply-To: name@example.com
 Content-Type: multipart/alternative; boundary="PHP-alt-4de4a7c8434ad5b8f6adb6e50c35b0da"
 MIME-Version: 1.0
Message-Id: <E1oJ4gz-006Rkx-8b@whub53.webhostinghub.com>

Any ideas what could be causing this?

NOTE: I am using "--PHP-alt-RandomHash" in the body as a method to send an HTML message with a plain text fallback. It is a demonstrated method found in various places.

My code:

$headers[] = $from;
$headers[] = "Reply-To: " . $fromemail;
$headers[] = "Content-Type: multipart/alternative; boundary=\"PHP-alt-" . $random_hash . "\"";
$headers[] = "MIME-Version: 1.0";

// plain text version
$body[] = "--PHP-alt-$random_hash";
$body[] = "Content-Type: text/plain; charset=\"utf-8\"";
$body[] = "Content-Transfer-Encoding: 8bit";
$body[] = "";
$body[] ="$message";

// html version
$body[] = "--PHP-alt-$random_hash";
$body[] = "Content-Type: text/html; charset=\"utf-8\"";
$body[] = "Content-Transfer-Encoding: 8bit";
$body[] = "";
$body[] = "<html><head>";
$body[] = "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />";
$body[] = "<title>$subject</title>";
$body[] = "</head>";  
$body[] = "<body>";
$body[] = $message;
$body[] = "</body></html>";
$body[] = "--PHP-alt-$random_hash--";

$success = mail($email, $subject, implode("\r\n", $body), implode("\r\n", $headers)); 

Solution

  • The change in behavior between php v8.1 and v7.4 was that using PHP_EOL caused the --PHP-alt- marker for alternative mail view to not be recognized.

    Changing it to "\r\n" fixed the issue. I thought I had gotten all of them initially, but there was one more instance of a PHP_EOL in the calling fn.