我有一个问题:直到今天,我一直使用一个包含以下内容的标题来使用PHP发送HTML邮件:
Content-type: text/html;
现在,我添加了添加附件的功能。为此,我不得不将这行更改为
Content-Type: multipart/mixed;
现在,使用multipart/mixed
,邮件中的其余部分——也就是普通文本——只会显示为text/plain
。我该如何确保附件能正常工作,同时仍然以HTML形式显示邮件正文?
我有一个问题:直到今天,我一直使用一个包含以下内容的标题来使用PHP发送HTML邮件:
Content-type: text/html;
现在,我添加了添加附件的功能。为此,我不得不将这行更改为
Content-Type: multipart/mixed;
现在,使用multipart/mixed
,邮件中的其余部分——也就是普通文本——只会显示为text/plain
。我该如何确保附件能正常工作,同时仍然以HTML形式显示邮件正文?
我尝试了答案1几个小时,但没有成功。我在这里找到了一个解决方案: http://www.finalwebsites.com/forums/topic/php-e-mail-attachment-script
这个解决方法非常好用 - 不到5分钟!你可能想要更改(就像我做的那样)第一个内容类型从text/plain变为text/html。
这是我的稍微修改过的版本,可以处理多个附件:
function mail_attachment($files, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
$uid = md5(uniqid(time()));
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-type:text/html; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= $message."\r\n\r\n";
foreach ($files as $filename) {
$file = $path.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$header .= "--".$uid."\r\n";
$header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use different content types here
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$header .= $content."\r\n\r\n";
}
$header .= "--".$uid."--";
return mail($mailto, $subject, "", $header);
}
$path
变量需要在所有 $files
数组中的 $filename
开头或结尾添加 /
,并且文件名不能包含空格,或者将 $file = $path.$filename;
更改为 $file = "$path/$filename";
。此外,这一行代码 $name = basename($file);
是无意义的,应该删除。 - Jeff PuckettMultiple or malformed newlines found in additional_header
错误,如 这里 所述。您还需要在第一个 Content-type
后删除双重 \r\n
(但这可能是 PHP7 特定的...不确定)。 - Shadi要发送带有附件的电子邮件,我们需要使用multipart/mixed MIME类型来指定在电子邮件中将包含混合类型。此外,我们还想使用multipart/alternative MIME类型来发送电子邮件的纯文本和HTML版本。看一下这个例子:
<?php
//define the receiver of the email
$to = 'youraddress@example.com';
//define the subject of the email
$subject = 'Test email with attachment';
//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date('r', time()));
//define the headers we want passed. Note that they are separated with \r\n
$headers = "From: webmaster@example.com\r\nReply-To: webmaster@example.com";
//add boundary string and mime type specification
$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";
//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents('attachment.zip')));
//define the body of the message.
ob_start(); //Turn on output buffering
?>
--PHP-mixed-<?php echo $random_hash; ?>
Content-Type: multipart/alternative; boundary="PHP-alt-<?php echo $random_hash; ?>"
--PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Hello World!!!
This is simple text email message.
--PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
<h2>Hello World!</h2>
<p>This is something with <b>HTML</b> formatting.</p>
--PHP-alt-<?php echo $random_hash; ?>--
--PHP-mixed-<?php echo $random_hash; ?>
Content-Type: application/zip; name="attachment.zip"
Content-Transfer-Encoding: base64
Content-Disposition: attachment
<?php echo $attachment; ?>
--PHP-mixed-<?php echo $random_hash; ?>--
<?php
//copy current buffer contents into $message variable and delete current output buffer
$message = ob_get_clean();
//send the email
$mail_sent = @mail( $to, $subject, $message, $headers );
//if the message is sent successfully print "Mail sent". Otherwise print "Mail failed"
echo $mail_sent ? "Mail sent" : "Mail failed";
?>
从示例中可以看出,发送带附件的电子邮件非常容易。在前面的示例中,我们使用了multipart/mixed MIME类型,并在其中包含了multipart/alternative MIME类型,该类型指定了电子邮件的两个版本。为了将附件包含在我们的消息中,我们从指定的文件中读取数据并将其编码为base64,在将其拆分成较小的块以确保它符合MIME规范,然后将其作为附件包含在内。
在PHP中,使用SWIFTMAIL可以很好地处理邮件附件。
从这里下载swiftmailer:http://swiftmailer.org/
请看下面的简单代码
包含文件
require_once('path/to/swiftMailer/lib/swift_required.php');
创建传输
//FOR SMTP
// Create the Transport
$transport = Swift_SmtpTransport::newInstance('smtp.googlemail.com', 465, 'ssl')
->setUsername('user@gmail.com')
->setPassword('gmailpassword');
或者
//FOR NORMAL MAIL
$transport = Swift_MailTransport::newInstance();
// Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance($subject)
->setFrom(array($from => $from))
->setTo($to)
->setBody($body);
$message->attach(Swift_Attachment::fromPath($filepath));
发送消息
$result = $mailer->send($message);
MIME-Version: 1.0
To: {email@domain}
Subject: {email-subject}
X-Priority: {2 (High)}
Content-Type: multipart/mixed; boundary="{mixed-boudary}"
--{mixed-boudary}
the entity content
--{mixed-boudary}--
因为电子邮件代理应该了解我们新插入实体的内容类型,所以我们必须在边界开头之后声明它。声明只是一个包含与实体兼容的参数/值的标头。
对于HTML正文内容,我的实体标头将如下所示:
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit
因此,整个被限定在边界内的身体最终会看起来像:
--{mixed-boudary}
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit
<html>
<head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head>
<body bgcolor="#FFFFFF" text="#000000">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque vel
dapibus arcu. Duis quam dui, ornare non mi nec, luctus faucibus massa. Vivamus
quis purus in erat euismod ullamcorper vitae eget dolor. Aliquam tempor erat
accumsan, consectetur ex et, rhoncus risus.
</body>
</html>
MIME-Version: 1.0
To: {email@domain}
Subject: {email-subject}
X-Priority: {2 (High)}
Content-Type: multipart/mixed; boundary="{mixed-boudary}"
--{mixed-boudary}
Content-Type: multipart/alternative; boundary="{alternative-boudary}"
--{alternative-boudary}
Content-Type: text/plain; charset=utf-8;
Content-Transfer-Encoding: 7bit
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque vel
dapibus arcu. Duis quam dui, ornare non mi nec, luctus faucibus massa. Vivamus
quis purus in erat euismod ullamcorper vitae eget dolor. Aliquam tempor erat
accumsan, consectetur ex et, rhoncus risus.
--{alternative-boudary}
Content-Type: text/html; charset=utf-8;
Content-Transfer-Encoding: 7bit
<html>
<head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head>
<body bgcolor="#FFFFFF" text="#000000">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque vel
dapibus arcu. Duis quam dui, ornare non mi nec, luctus faucibus massa. Vivamus
quis purus in erat euismod ullamcorper vitae eget dolor. Aliquam tempor erat
accumsan, consectetur ex et, rhoncus risus.
</body>
</html>
--{alternative-boudary}--
--{mixed-boudary}
Content-Type: application/pdf; name="myfile.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="myfile.pdf"
JVBERi0xLjINOCAwIG9iag08PCAvTGVuZ3RoIDkgMCBSIC9GaWx0ZXIgL0ZsYXRlRGVjb2Rl
ID4+DXN0cmVhbQ1oQ51bbY/cNg7+BfsfhAUO11w3riW/B7gPaZEAAdpcm06RL8EBzoyn68uM
vZ3xZLv//khKsuUxNaMNiiabpUg+pKiHsmxJEcN/UsgiilP4ab2/+XF1I81vszSqclHIOEpj
sdrf/PC2EFVUpmK1vXkZxVKs1uJlJJVYPYrvPra7XVvvxYdIrE7rL83hhVj97+bNyjUoFam7
FnOB+tubGI3FZEkwmhpKXpVRnqJi0PCyjBJ1DjyOYqWBxxXp/1h3X+ov9abZt434pV0feoG/
ars/xU/9/qEZmm7diJ+abmgOr0TGeFNFEuXx5M4B95Idns/QAaJMI1IpKeXi9+ZhaPafm4NQ
cRwzNpK0iirlRvisRBZpVJa+PP51091kkjBWBXrJxUuZRjIXh0Z8FN3MnB5X5st5Kay9355n
--{mixed-boudary}--
提示
使用您喜欢的电子邮件客户端(我的是Thunderbird),向自己发送一封纯文本、一封仅包含HTML内容、一封混合内容的邮件,以及每个之前的邮件都附带一个文件附件。当您收到该邮件时,请查看其源代码(查看 -> 消息源)。
@编辑:可以在此处找到一个非常详细记录的案例研究和PHP示例。