2011-09-02 21 views
5

Ho uno script PHP che invia un'email HTML con un'immagine allegata. Funziona bene, tuttavia, non riesco a visualizzare l'allegato in un tag <img> nel corpo dell'e-mail. Il file allegato si chiama postcard.png e il nome file originale sul server è 4e60348f83f2f.png. Ho provato a fornire l'URL dell'immagine come varie cose: cid:postcard.png, cid:4e60348f83f2f.png, postcard.png e 4e60348f83f2f.png. Niente funziona.come inviare un messaggio di posta elettronica HTML con un'immagine allegata in linea con PHP

Penso che la parte chiave che sto facendo male è qui, perché questo lo rende un allegato separato invece di un allegato in linea che posso usare:

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

Ho provato a cambiare in modo da utilizzare un CID ma io non so davvero come fare, e questa non' lavoro a tutti:

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

Ecco il codice completo: (Si basa su this code da un commento nella pagina 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

Utilizzare [PHPMailer] (http://phpmailer.worxware.com) o [Swiftmailer] (http://swiftmailer.org). Entrambi consentono gli allegati in linea con assolutamente NO PAIN, a differenza di ciò che stai passando per creare il messaggio MIME da zero. –

+0

Non è che non sia possibile farlo a mano, ma usare Swiftmailer o PHPMailer sarebbe molto meno ingombrante. - possibile duplicato di [Invia email con PHPMailer - immagine incorporata nel corpo] (http://stackoverflow.com/questions/3708153/send-email-with-phpmailer-embed-image-inbody) – mario

+1

@Marc B: Non so, ho tirato una benda a digitare una volta con PHPMailer, è stato un po 'doloroso. –

risposta

14

Ho finalmente trovato la risposta, che risulta essere straordinariamente semplice. This page è ciò che mi ha aiutato a capirlo, ma dimostrerò le parti di cui avevo bisogno per farlo in seguito.

Prima di tutto, c'è la creazione della stringa di confine, e l'immagine, codificato correttamente e 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'))); 

Nella parte HTML del messaggio, l'immagine viene fatto riferimento in questo modo (utilizzando la stringa di confine):

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

quindi si crea un'altra parte della posta elettronica al di sotto della parte HTML per l'allegato in linea, in questo modo:

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

... e questo è quello! Più facile che implementare PHPmailer o una qualsiasi delle altre librerie, se questo è tutto ciò che stai facendo. Senza dubbio per attività più complicate, ti consigliamo di procurarti una di queste librerie.

+0

Non posso allegare in base a questa risposta, mi piace questo: http://pastebin.com/z8LqAHCB –

0

Vorrei raccomandare l'uso di PHPMailer ma dal momento che dici di non voler suggerire questa soluzione rapida.

Inserisci l'URL assoluto all'interno di un tag img, se invii un'email HTML, funzionerà.

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

Grazie, tuttavia, sto cancellando l'immagine dal server subito dopo aver inviato l'e-mail, in modo che non funzioni, così come molti client di posta elettronica non consentono l'hotlinking nelle e-mail. – brentonstrine

+0

Utilizzando questo metodo l'immagine verrà bloccata in vari client di posta elettronica – ljelewis

Problemi correlati