Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
869 views
in Technique[技术] by (71.8m points)

how to send an HTML email with an inline attached image with PHP

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.

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:

Content-Transfer-Encoding: base64
Content-ID: <$fname> // i.e.: postcard.png

Here's the full code: (It's based on this code from a comment in the php mail() page.)

<?php
$to      = "recipient@email.com";
$email   = "sender@email.com";
$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>";
?>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I finally found the answer, which turns out to be remarkably simple. This page is 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):

<img src="cid:PHP-CID-{$sep}">

Then you create another part of the email below the HTML part for the inline attachment, like this:

--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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...