2011-09-02 10 views
5

Tengo un script PHP que envía un correo electrónico HTML con una imagen adjunta. Funciona a la perfección, sin embargo, no puedo hacer que el archivo adjunto se muestre en una etiqueta <img> en el cuerpo del correo electrónico. El archivo adjunto se llama postcard.png y el nombre de archivo original en el servidor es 4e60348f83f2f.png. Intenté dar la URL de la imagen como varias cosas: cid:postcard.png, cid:4e60348f83f2f.png, postcard.png y 4e60348f83f2f.png. Nada funciona.cómo enviar un correo electrónico HTML con una imagen adjunta en línea con PHP

Creo que la parte clave que estoy haciendo mal está aquí, porque esto hace que sea un accesorio separado en lugar de datos adjuntos en línea que puede utilizar:

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

He intentado cambiar a utilizar un CID pero no se sabe muy bien cómo hacerlo, y esto ni' trabajo en absoluto:

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

Aquí está el código completo: (Se basa en this code de un comentario en la página 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

Utilice [PHPMailer] (http://phpmailer.worxware.com) o [Swiftmailer] (http://swiftmailer.org). Ambos permiten los archivos adjuntos en línea sin ABSOLUTAMENTE NINGÚN DOLOR, a diferencia de lo que está pasando para construir el mensaje MIME desde cero. –

+0

No es que no sea posible hacerlo a mano, pero usar Swiftmailer o PHPMailer sería mucho menos engorroso. - posible duplicado de [Enviar correo electrónico con PHPMailer - incrustar imagen en el cuerpo] (http://stackoverflow.com/questions/3708153/send-email-with-phpmailer-embed-image-in-body) – mario

+1

@Marc B: No sé, hice un padrastro escribiendo una vez con PHPMailer, fue algo doloroso. –

Respuesta

14

Finalmente encontré la respuesta, que resulta notablemente simple. This page es lo que me ayudó a resolverlo, pero voy a demostrar las partes que necesitaba para hacerlo a continuación.

En primer lugar, está la creación de la serie de límite, y la imagen, correctamente codificados y fragmentada:

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

En la parte HTML del correo electrónico, la imagen se hace referencia como esto (utilizando la cadena de límite):

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

a continuación, crear otra parte del correo electrónico por debajo de la parte HTML para la fijación en línea, así:

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

... ¡y eso es todo! Es más fácil que implementar PHPmailer o cualquiera de las otras bibliotecas, si esto es todo lo que estás haciendo. Sin duda para tareas más complicadas, querrás obtener una de esas bibliotecas.

+0

No puedo adjuntar de acuerdo con esta respuesta, me gusta esto: http://pastebin.com/z8LqAHCB –

0

Recomendaría usar PHPMailer pero como dice que no quiere, le sugiero esta solución rápida.

Ponga la URL absoluta dentro de una etiqueta img, si envía un correo electrónico HTML, funcionará.

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

Gracias, sin embargo, estoy eliminando la imagen del servidor inmediatamente después de enviar el correo electrónico, por lo que no funcionará, así como porque muchos clientes de correo electrónico no permiten hotlinking en los correos electrónicos. – brentonstrine

+0

Usando este método la imagen será bloqueada en varios clientes de correo electrónico – ljelewis

Cuestiones relacionadas