如何使用 PHP 发送带有内嵌附加图像的 HTML 电子邮件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7288614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to send an HTML email with an inline attached image with PHP
提问by brentonstrine
I have a PHP script which sends an HTML email with an attached image. It works beauifully, however, I can't get the attachment to display in an <img>
tag in the email body. The attached file is called postcard.png
and the original filename on the server is 4e60348f83f2f.png
. I've tried giving the image URL as various things: cid:postcard.png
, cid:4e60348f83f2f.png
, postcard.png
, and 4e60348f83f2f.png
. Nothing works.
我有一个 PHP 脚本,它发送带有附加图像的 HTML 电子邮件。它工作得很好,但是,我无法让附件显示在<img>
电子邮件正文的标签中。调用附加文件postcard.png
,服务器上的原始文件名为4e60348f83f2f.png
. 我试着给图像URL各种东西:cid:postcard.png
,cid:4e60348f83f2f.png
,postcard.png
,和4e60348f83f2f.png
。什么都行不通。
I think the key part that I'm doing wrong is here, because this makes it a separated attachment instead of an inline attachment that I can use:
我认为我做错的关键部分在这里,因为这使它成为一个单独的附件而不是我可以使用的内联附件:
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="$fname" // i.e.: "postcard.png"
I've tried changing it to use a CID but I don't really know how to do that, and this didnt' work at all:
我尝试将其更改为使用 CID,但我真的不知道该怎么做,这根本不起作用:
Content-Transfer-Encoding: base64
Content-ID: <$fname> // i.e.: postcard.png
Here's the full code: (It's based on this codefrom a comment in the php mail()
page.)
这是完整的代码:(它基于来自 php页面注释中的此代码mail()
。)
<?php
$to = "[email protected]";
$email = "[email protected]";
$name = "Namename";
$subject = "An inline image!";
$comment = "Llookout <b>Llary</b> it's <br> the <b>Ll</b>andllord!<br><img src='cid:postcard.png'><br><img src='cid:4e60348f83f2f.png'><img src='postcard.png'><br><img src='4e60348f83f2f.png'>";
$To = strip_tags($to);
$TextMessage =strip_tags(nl2br($comment),"<br>");
$HTMLMessage =nl2br($comment);
$FromName =strip_tags($name);
$FromEmail =strip_tags($email);
$Subject =strip_tags($subject);
$boundary1 =rand(0,9)."-"
.rand(10000000000,9999999999)."-"
.rand(10000000000,9999999999)."=:"
.rand(10000,99999);
$boundary2 =rand(0,9)."-".rand(10000000000,9999999999)."-"
.rand(10000000000,9999999999)."=:"
.rand(10000,99999);
$filename1 = "4e60348f83f2f.png"; //name of file on server with script
$handle =fopen($filename1, 'rb');
$f_contents =fread($handle, filesize($filename1));
$attachment=chunk_split(base64_encode($f_contents));
fclose($handle);
$ftype ="image/png";
$fname ="postcard.png"; //what the file will be named
$attachments='';
$Headers =<<<AKAM
From: $FromName <$FromEmail>
Reply-To: $FromEmail
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="$boundary1"
AKAM;
$attachments.=<<<ATTA
--$boundary1
Content-Type: $ftype;
name="$fname"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="$fname"
$attachment
ATTA;
$Body =<<<AKAM
This is a multi-part message in MIME format.
--$boundary1
Content-Type: multipart/alternative;
boundary="$boundary2"
--$boundary2
Content-Type: text/plain;
charset="windows-1256"
Content-Transfer-Encoding: quoted-printable
$TextMessage
--$boundary2
Content-Type: text/html;
charset="windows-1256"
Content-Transfer-Encoding: quoted-printable
$HTMLMessage
--$boundary2--
$attachments
--$boundary1--
AKAM;
// Send email
$ok=mail($To, $Subject, $Body, $Headers);
echo $ok?"<h1> Mail sent!</h1>":"<h1> Mail not sent!</h1>";
?>
回答by brentonstrine
I finally found the answer, which turns out to be remarkably simple. This pageis what helped me figure it out, but I'll demonstrate the parts that I needed to get it done below.
我终于找到了答案,结果非常简单。这个页面帮助我弄清楚了,但我将在下面演示完成它所需的部分。
First off, there's the creation of the boundary string, and the image, correctly encoded and chunked:
首先,创建边界字符串,以及正确编码和分块的图像:
// Create a boundary string. It needs to be unique (not in the text) so ...
// We are going to use the sha1 algorithm to generate a 40 character string:
$sep = sha1(date('r', time()));
// Also now prepare our inline image - Also read, encode, split:
$inline = chunk_split(base64_encode(file_get_contents('figure.gif')));
In the HTML part of the email, the image is referenced like this (using the boundary string):
在电子邮件的 HTML 部分,图像是这样引用的(使用边界字符串):
<img src="cid:PHP-CID-{$sep}">
Then you create another part of the email below the HTML part for the inline attachment, like this:
然后,您在 HTML 部分下方为内嵌附件创建电子邮件的另一部分,如下所示:
--PHP-related-{$sep}
Content-Type: image/gif
Content-Transfer-Encoding: base64
Content-ID: <PHP-CID-{$sep}>
{$inline}
...and that is that! Easier than implementing PHPmailer or any of the other libraries, if this is all you're doing. No doubt for more complicated task, you'll want to get one of those libraries.
……就是这样!比实现 PHPmailer 或任何其他库更容易,如果这就是你所做的一切。毫无疑问,对于更复杂的任务,您会想要获得这些库之一。
回答by Charles Forest
I would recommend using PHPMailer but since you say you don't want to I suggest this quick fix.
我建议使用 PHPMailer 但既然你说你不想我建议这个快速修复。
Put the absolute URL inside an img tag, if you do send an HTML email, it will work.
将绝对 URL 放在 img 标签中,如果您确实发送了 HTML 电子邮件,它将起作用。
<img src="http://example.com/image.jpg"/>