PHP邮件发送坏消息头



我正在努力从PHP脚本发送电子邮件。当mail()函数被触发,并且收件人的邮箱由特定服务(seznam.cz)托管,并且邮件被下载到邮件客户端(Mozilla Thunderbird)并且ESET反病毒检查它时,消息似乎被破坏了。

我认为,问题是由反病毒软件在邮件消息中插入特殊标题并在其后面留下空行引起的:

...
Subject: =?UTF-8?B?Tm92w70gxI1sZW4gd2VidSBBU1AgxIxSIQ==?=
X-EsetId: 37303A298C7FEE69657363
X-PHP-Originating-Script: 80:script.php
MIME-Version: 1.0
Content-type:text/html;charset=UTF-8
...

我的电子邮件客户端认为消息是纯文本,并以X-PHP-Originating-Script行开始。消息的其余部分包括所有HTML标记。

这是我用来发送邮件的脚本:

$subject = mb_encode_mimeheader('Subject text');
$emailBody = '<!DOCTYPE html>
<html lang="cs">
...
</html>';
$emailAltBody = "...";
$headers = "MIME-Version: 1.0" . "rn";
$headers .= "Content-type:text/html;charset=UTF-8" . "rn";
$headers .= 'From: <email.address@example.com>' . "rn";
$result = mail("email.address@example.com", $subject, $emailBody, $headers);

然而,当使用Laravel框架时,电子邮件被正确发送和显示。我比较了差异并意识到,X-PHP-Originating-Script标头不是由Laravel发送的。

这可能是原因吗?我该如何修复它?

这可能是不同的行分隔符的问题。

在PHP 7.4之前,x -PHP- origin - script之后的分隔符仅为n(在PHP 8中更改为使用rn,甚至最近在master中更改为基于其他因素的决定)。

由于所有其他标头都是使用rn连接的,因此防病毒程序在添加标头时可能会造成一些混淆。这将导致双换行,客户端将其解释为正文的开始。

如果使用显示所有字符(包括nr)的编辑器查看原始消息,您可能会更好地理解它。

解决方案是匹配PHP版本的行尾,或者在PHP .ini中删除所有设置mail.add_x_header = OffX-PHP-Originating-Script头。