PHP邮件函数在消息文本中随机添加一个空格


PHP mail function randomly adds a space to message text

我有一个非常简单的PHP脚本,类似于:

while ($condition){
    echo "<a href="thanks.php?id=".$id."> THANKS </a>";
}

当然,我还有一些代码,但这并不重要。一旦我创建了这段代码,脚本就会向用户发送一封电子邮件。

收件箱

每一行的链接都是可以的,除了LAST ONE以这种方式显示链接:

    tha nks.php?id.....

它在代码之间添加了一个空格。

这种情况只发生在hotmail中。Gmail、雅虎和其他一切都很好。

我知道这很晚了,但有一个替代解决方案对我有效:

使用这一行使用base64:对您的整个消息进行编码

$message = chunk_split(base64_encode($message));

然后,把这个附加到你的标题:

$headers .= "Content-Transfer-Encoding: base64'r'n'r'n";

这将告诉邮件客户端您的消息是base64编码的。

karancan的解决方案应该有效,但根本原因是Hobo所说的。SMTP协议要求行限制为1000个字符(实际上是998个字符加上一个CR-LF)。如果您的行长度超过1000个字符,则每998个字符将插入一个CR-LF。

因此,如果你用一堆$message .= "more text";构建你的$消息,一旦这一行的长度超过900个字符,你就会遇到这个错误。但这很令人困惑,因为空格似乎是间歇性的,尤其是当你构建HTML消息时,因为有时换行符会出现在非常好的位置。

简单的解决方案是在行的末尾添加一个'r'n'

有趣的是,这些表单有效:

$message .= "<tr><td>1</td><td>2</td>'r'n";
$message .= '<tr><td>1</td><td>2</td>'."'r'n";

但事实并非如此:

$message .= '<tr><td>1</td><td>2</td>'r'n';

'r'n必须用双引号括起来,否则字符将被添加到文本中,而不是创建回车符/换行符。

@不过karancan是正确的,如果您对消息进行base64编码,则可以跳过添加'r'n,并添加所需的标头。

遇到了同样的问题,并尝试了大多数解决方案,但对我来说都不起作用。似乎当这行太长而无法发送邮件时,它会添加大约900个字符的空格。所以下面添加换行符的解决方案对我有效。

邮件($to,$subject,wordwrap($message),$headers);

2019工作答案

SMTP协议要求每行后面都有一个CRLF,它包含998个以上的字符。基本上,1000的每一行都必须在其末尾包含CRLF字符。

此问题最简单的工作解决方案是发送在base64中编码的电子邮件内容,然后添加一个头,告诉邮件客户端内容是在base64编码的然后发送电子邮件。

贝娄就是一个很好的例子。我用一封大约有27000个字符的邮件进行了测试,它运行得很好。在这次更新之前,它破坏了我HTML内容中的关键链接。

<?php
// used for date() function
date_default_timezone_set('Europe/Bucharest');

$to = 'john.doe@company.com';
$from = 'john.doe@company.com';
$fromName = 'John Doe';
$subject = "Html email test at ".date('H:i:s');

// Set content-type header for sending HTML email
$headers = "MIME-Version: 1.0" . "'r'n";
$headers .= "Content-type:text/html;charset=UTF-8" . "'r'n";
$headers .= "Content-Transfer-Encoding: base64" . "'r'n";

// Additional headers
$headers .= 'From: '.$fromName.'<'.$from.'>' . "'r'n";
$headers .= 'Cc: welcome@example.com' . "'r'n";
$headers .= 'Bcc: welcome2@example.com' . "'r'n";

$extremely_long_html_email = "<!DOCTYPE html PUBLIC '"-//W3C//DTD XHTML 1.0 Transitional//EN'" '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'">
<html xmlns='"http://www.w3.org/1999/xhtml'">
<head>
    <meta http-equiv='"X-UA-Compatible'" content='"IE=edge'"/>
    <meta http-equiv='"Content-Type'" content='"text/html; charset=utf-8'"/>
    <meta name='"viewport'" content='"width=device-width, initial-scale=1'"/>
    <title>TEST</title>
    </head>
    <body>
        Very long HTML code. I stripped mine due to copyright issues.
    </body>
</html>";

// Send email
if(mail($to, $subject, base64_encode($extremely_long_html_email), $headers)){
    echo 'Email has sent successfully.';
}else{
    echo 'Email sending failed.';
}
?>

TL;DR在使用base64_encode($html_email)函数发送html内容之前,添加额外的标头$headers .= "Content-Transfer-Encoding: base64" . "'r'n";并对其进行编码。

我见过当行太长时,sendmail会插入字符。这里的情况并非如此(因为其他客户处理得很好),但我想知道hotmail是否有您遇到的线路长度限制。

如果你在echo(即)中插入一行换行符,会有什么不同吗

while ($condition){
    echo "<a href='"thanks.php?id=".$id."'"> THANKS </a>'n";
}

如果您使用PHPMailer或Joomla CMS(使用PHPMail),使用utf-8和base64对您的消息进行编码的适当代码(相当于karancan的解决方案)是:

$mailer->CharSet = 'utf-8';
$mailer->Encoding = 'base64'

请注意,不应chunk_split(base64_encode($emailBody));,因为一旦将Encoding设置为base64,PHPMailer就会自动为您执行此操作,并且您不希望对电子邮件正文base64进行两次编码:)