我有一个非常简单的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: base64rnrn";
这将告诉邮件客户端您的消息是base64编码的。
karancan的解决方案应该有效,但根本原因是Hobo所说的。SMTP协议要求行限制为1000个字符(实际上是998个字符加上一个CR-LF)。如果您的行长度超过1000个字符,则每998个字符将插入一个CR-LF。
因此,如果你用一堆$message .= "more text";
构建你的$消息,一旦这一行的长度超过900个字符,你就会遇到这个错误。但这很令人困惑,因为空格似乎是间歇性的,尤其是当你构建HTML消息时,因为有时换行符会出现在非常好的位置。
简单的解决方案是在行的末尾添加一个rn
。
有趣的是,这些表单有效:
$message .= "<tr><td>1</td><td>2</td>rn";
$message .= '<tr><td>1</td><td>2</td>'."rn";
但事实并非如此:
$message .= '<tr><td>1</td><td>2</td>rn';
rn
必须用双引号括起来,否则字符将被添加到文本中,而不是创建回车符/换行符。
@不过karancan是正确的,如果您对消息进行base64编码,则可以跳过添加rn
,并添加所需的标头。
遇到了同样的问题,并尝试了大多数解决方案,但对我来说都不起作用。似乎当这行太长而无法发送邮件时,它会添加大约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" . "rn";
$headers .= "Content-type:text/html;charset=UTF-8" . "rn";
$headers .= "Content-Transfer-Encoding: base64" . "rn";
// Additional headers
$headers .= 'From: '.$fromName.'<'.$from.'>' . "rn";
$headers .= 'Cc: welcome@example.com' . "rn";
$headers .= 'Bcc: welcome2@example.com' . "rn";
$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" . "rn";
并对其进行编码。
我见过当行太长时,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进行两次编码:)