2011-09-02 14 views
5

Mam skrypt PHP, który wysyła wiadomość e-mail w formacie HTML z załączonym obrazem. Działa to doskonale, jednak nie mogę uzyskać załącznika do wyświetlania w tagu <img> w treści wiadomości e-mail. Załączony plik nosi nazwę postcard.png, a oryginalna nazwa pliku na serwerze to 4e60348f83f2f.png. Próbowałem podać adres URL obrazu jako różne rzeczy: cid:postcard.png, cid:4e60348f83f2f.png, postcard.png i 4e60348f83f2f.png. Nic nie działa.Jak wysłać wiadomość e-mail w formacie HTML z dołączonym obrazem w wierszu z PHP

Myślę, że kluczowym elementem, że robię źle tutaj, ponieważ to sprawia, że ​​jest on oddzielony przywiązanie zamiast załączniki inline, że mogę używać:

Content-Transfer-Encoding: base64 
Content-Disposition: attachment; 
    filename="$fname" // i.e.: "postcard.png" 

Próbowałem zmieniając go użyć CID, ale ja naprawdę nie wiem jak to zrobić, i to zrobił”praca w ogóle:

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

Oto pełny kod: (jest on oparty na this code z komentarzem na stronie 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>"; 
?> 
+2

Użyj [PHPMailer] (http://phpmailer.worxware.com) lub [Swiftmailer] (http://swiftmailer.org). Oba pozwalają na załączniki w linii z absolutnie BEZ BARANIA, w przeciwieństwie do tego, co robisz, aby zbudować wiadomość MIME od zera. –

+0

Nie jest tak, że nie można tego zrobić ręcznie, ale używanie Swiftmailera lub PHPMailera byłoby o wiele mniej kłopotliwe. - możliwy duplikat wiadomości [Wyślij e-mail z PHPMailer - umieść obraz w ciele] (http://stackoverflow.com/questions/3708153/send-email-with-phpmailer-embed-image-in-body) – mario

+1

@Marc B: Nie wiem, raz nacisnąłem pismo z PHPMailerem, było to trochę bolesne. –

Odpowiedz

14

W końcu znalazłem odpowiedź, która okazała się zaskakująco prosta. This page jest tym, co pomogło mi to rozgryźć, ale zademonstruję części, których potrzebowałem, aby to zrobić poniżej.

Po pierwsze, jest stworzenie łańcucha granicznej, a obraz, poprawnie zakodowany i pofragmentowane:

// 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'))); 

W części HTML wiadomości e-mail, obraz jest określany następująco (przy użyciu ciąg brzegowy):

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

Następnie należy utworzyć kolejną część email poniżej strony HTML do mocowania inline, podobnie jak to:

--PHP-related-{$sep} 
Content-Type: image/gif 
Content-Transfer-Encoding: base64 
Content-ID: <PHP-CID-{$sep}> 
{$inline} 

... i to jest to! Łatwiejsze niż wdrożenie PHPmailera lub dowolnej innej biblioteki, jeśli to wszystko, co robisz. Bez wątpienia dla bardziej skomplikowanego zadania, będziesz chciał dostać jedną z tych bibliotek.

+0

Nie mogę dołączyć zgodnie z tą odpowiedzią, mam na przykład to: http://pastebin.com/z8LqAHCB –

0

Polecam używanie PHPMailera, ale ponieważ mówisz, że nie chcesz, sugeruję tę szybką naprawę.

Umieść bezwzględny adres URL w tagu img, jeśli wyślesz wiadomość HTML, będzie działać.

<img src="http://example.com/image.jpg"/> 
+1

Dzięki temu jednak usuwam obraz z serwera natychmiast po wysłaniu wiadomości e-mail, więc to nie zadziała, a także dlatego, że wielu klientów poczty e-mail nie zezwala na tworzenie linków w wiadomościach e-mail. – brentonstrine

+0

Używając tej metody obraz zostanie zablokowany w różnych klientach poczty elektronicznej – ljelewis

Powiązane problemy