PHP的mail()函数会混淆电子邮件中的HTML

时间:2011-06-20 20:43:26

标签: php email

所以我有以下代码。它应该发送在先前屏幕中编辑的HTML电子邮件。但是,一旦发送电子邮件,在html标签中,每个标签的第一个双引号和字母就会丢失,例如,

<span style="something">

成为

<span style=omething">

奇怪的部分是,如果回显到屏幕上,信息打印得很好,所以我认为它与如何发送到整个功能有什么关系,但它是如何发送到邮件的()功能...但我不知道问题是什么。这是代码,没有变量的所有变量,因为我不认为它特别相关。

//start of the headers
$headers = "From: $from_name<$from_email>\n";
$headers .= "Reply-To: <$reply_to>\n"; 
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/related; type=\"multipart/alternative\"; boundary=\"----=MIME_BOUNDRY_main_message\"\n"; 
$headers .= "X-Sender: $from_name<$from_email>\n";
$headers .= "X-Mailer: PHP4\n";
$headers .= "X-Priority: 3\n"; //1 = Urgent, 3 = Normal
$headers .= "Return-Path: <$from_email>\n"; 
$headers .= "This is a multi-part message in MIME format.\n";
$headers .= "------=MIME_BOUNDRY_main_message \n"; 
$headers .= "Content-Type: multipart/alternative; boundary=\"----=MIME_BOUNDRY_message_parts\"\n"; 

$message = "------=MIME_BOUNDRY_message_parts\n";
$message .= "Content-Type: text/html\r\n";  //changed to support html
$message .= "Content-Transfer-Encoding: quoted-printable\n"; 
$message .= "\n"; 
/* note: add HTML by changing the Content-Type to text/html */
////TEST 1 - this is where i attempted to hardcode some code in to see if it would send properly: it wouldn't. printed fine though.
$message .="<font class=\"Apple-style-span\" face=\"'Courier New'\" size=\"5\">\n"; 
$message .= "bbbbb<b>bbbb<i>bbb<u>bbb<font class=\"Apple-style-span\" color=\"#000099\">\n"; 
$message .= "bbbbb<span class=\"Apple-style-span\" style=\"background-color: rgb(102, 255, 204);\">bbbbbb</span></font></u></i></b></font>\n";
/////end test 1
$message .= $body.'\n';
$message .= "\n\n"; 
$message .= "------=MIME_BOUNDRY_message_parts--\n"; 
if($file_present==1){ // added this to fix empty file bug
$message .= "\n"; 
$message .= "------=MIME_BOUNDRY_main_message\n"; 
$message .= "Content-Type: application/octet-stream;\n\tname=\"" . $attachment_name . "\"\n";
$message .= "Content-Transfer-Encoding: base64\n";
$message .= "Content-Disposition: attachment;\n\tfilename=\"" . $attachment_name . "\"\n\n";
$message .= $data; //The base64 encoded message 
$message .= "\n"; 
$message .= "------=MIME_BOUNDRY_main_message--\n"; 
}
echo $message; //this is where it echoes fine, with all tags intact
// send the message
   if( mail("$to_name<$to_email>", $subject, $message, $headers)){ //this is where it goes wrong.
     echo("<p>Message successfully sent to ".$to_email.".</p>");
  } else {
   echo("<p>Message delivery to ".$to_email." failed.</p>");
  }

6 个答案:

答案 0 :(得分:1)

使用PHP输出HTML时,我发现更容易做到这样的事情:

$content = '<span class="something">' . $someDynamicVariable . '</span>';

这避免了逃避双引号的噩梦。

答案 1 :(得分:1)

$headers .= "...[snip]... boundary=\"----=MIME_BOUNDRY_message_parts\"\n"; 
                                    ^--here                          ^--here

您将引号嵌入到边界字符串中,但不使用实际边界的引号。

内容类型标题的边界部分不应包含引号。

对于多行字符串生成,尤其是嵌入式引号(例如HTML),我强烈建议您使用HEREDOC:

$message .= <<<EOL
<font class="Apple-style-span" face="'Courier New'" size="5">
bbbbb<b>bbbb<i>bbb<u>bbb<font class="Apple-style-span" color="#000099">
bbbbb<span class="Apple-style-span" style="background-color: rgb(102, 255, 204);">bbbbbb</span></font></u></i></b></font>
EOL;

比重复连接方法更易读,并且不需要引号上的任何转义。作为奖励,你甚至可以像在PHP中使用任何其他普通的双引号字符串一样将变量嵌入到字符串中。

答案 2 :(得分:0)

在某个地方,你有一个未转义的引用,可能通过PHP变量输入到HTML中。您需要对将在HTML中结束的所有变量调用htmlentities($variable, ENT_QUOTES)

答案 3 :(得分:0)

mail()可能会将双引号视为特殊符号,并且因为您要将所有字符串发送到引号内,因此mail()可能无法告知字​​符串的结束位置以及它再次继续的位置。

我建议用单引号替换字符串中的所有双引号,因为HTML会允许这样做,因为它具有灵活性。

所以试试这个

<span style='Something'>

答案 4 :(得分:0)

好吧,我一直在回答我的老问题。想我应该发布我是如何解决这个问题的。我最初的假设是正确的:信息正文没有任何问题。问题是......

标题!不,这对我来说没有意义。但在我最初删除X-Sender /相关标头信息后,一切都开始发送几乎没问题。然后我将边界更改为随机值,突然一切正常。任何能够向我解释为什么会发生这种情况的人都欢迎,但我很高兴它的确有效。

答案 5 :(得分:0)

我认为这与Content-Transfer-Encoding有关:引用的可打印(see here)。