php email email-attachments

Enviar múltiples archivos adjuntos en un correo electrónico usando PHP



email email-attachments (2)

Tengo problemas para enviar un correo electrónico con varios archivos adjuntos. Aquí está el código:

<?php if(isset($_POST[''sendEmail''])) { foreach($_FILES[''uploadEmail''][''error''] as $key=>$value){ if(!$_FILES[''uploadEmail''][''error''][$key]){ $target_path = ""; $target_path = $target_path . basename( $_FILES[''uploadEmail''][''name''][$key]); if(move_uploaded_file($_FILES[''uploadEmail''][''tmp_name''][$key], $target_path)){ $files[] = $_FILES[''uploadEmail''][''name''][$key]; } } } $toEmails = explode(",",$_POST[''toEmail'']); $count = count($toEmails); $i = 0; $j = 1; $k = 100; $bcc = ''''; while($i<$count){ $bcc .= $toEmails[$i].","; if($j==$k || $i==$count-1){ $j=1; //echo $bcc.''<br />''.$sub.''<br />''.$message.''<br /><br />''; $from = ''[email protected]''; $sub = $_POST[''subject'']; $message = $_POST[''message'']; ///////////////////////// $headers = ''From:''. $from . "/r/n"; $headers .= "Bcc:". $bcc . "/r/n"; // boundary $semi_rand = md5(time()); $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; // headers for attachment $headers .= "/nMIME-Version: 1.0/n" . "Content-Type: multipart/mixed;/n" . " boundary=/"{$mime_boundary}/""; // multipart boundary $message = "This is a multi-part message in MIME format./n/n" . "--{$mime_boundary}/n" . "Content-Type: text/html; charset=/"iso-8859-1/"/n" . "Content-Transfer-Encoding: 7bit/n/n" . $message . "/n/n"; $message .= "--{$mime_boundary}/n"; // preparing attachments for($x=0;$x<count($files);$x++){ $file = fopen($files[$x],"rb"); //echo "<br>".filesize($files[$x]); $data = fread($file,filesize($files[$x])); fclose($file); $data = chunk_split(base64_encode($data)); $message .= "Content-Type: {/"application/octet-stream/"};/n" . " name=/"$files[$x]/"/n" . "Content-Disposition: attachment;/n" . " filename=/"$files[$x]/"/n" . "Content-Transfer-Encoding: base64/n/n" . $data . "/n/n"; $message .= "--{$mime_boundary}/n"; } // send ///////////////////////// mail('''',$sub,$message,$headers); $bcc = ''''; }else{ $j++; } $i++; } } ?> <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script> <script src="http://js.nicedit.com/nicEdit-latest.js" type="text/javascript"></script> <script type="text/javascript">bkLib.onDomLoaded(function() { new nicEditor().panelInstance(''message''); // new nicEditor({fullPanel : true}).panelInstance(''area2''); });</script> </head> <body> <form method="POST" enctype="multipart/form-data"> <table> <tr><td><label for="toEmail">Send To : </label></td><td><textarea id="toEmail" name="toEmail" cols="100" rows="10"></textarea></td></tr> <tr><td><label for="subject">Subject : </label></td><td><input type="text" name="subject" id="subject" size="98"></td></tr> <tr><td><label for="toEmail">Message : </label></td><td><textarea id="message" name="message" cols="100" rows="10"></textarea></td></tr> <tr><td><label for="upload[]">Attachments:</label></td><td></td></tr> <tr><td><label>1</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>2</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>3</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>4</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>5</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>6</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>7</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>8</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>9</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td><label>10</label></td><td><input type="file" name="uploadEmail[]"></td></tr> <tr><td colspan="2" align="center"><input type="submit" value="Send Email" name="sendEmail" id="sendEmail"></td></tr> </table> </form> <body> </html>

Recibí correo pero no pude encontrar ningún archivo adjunto. ¿Alguien sabe qué podría estar mal?

Aquí hay un cuerpo de correo electrónico que recibí por correo:

MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="==Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x" This is a multi-part message in MIME format. --==Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: 7bit ds fsdfsdfsdfsdfsdfsdfsf sffdfsdfsdfs fsdfdf sdf s --==Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x Content-Type: {"application/octet-stream"}; name="/tmp/phpHFTvAw" Content-Disposition: attachment; filename="Lighthouse.jpg" Content-Transfer-Encoding: base64 --==Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x Content-Type: {"application/octet-stream"}; name="/tmp/phpyX67HR" Content-Disposition: attachment; filename="Penguins.jpg" Content-Transfer-Encoding: base64 --==Multipart_Boundary_x2d454346f03d2c19cfefc838ce4d8623x


Responder

Hay algunos problemas con su código que he detallado a continuación.

  • Terminaciones de línea

    $headers = ''From:''. $from . "/r/n"; $headers .= "Bcc:". $bcc . "/r/n"; ... // headers for attachment $headers .= "/nMIME-Version: 1.0/n" . "Content-Type: multipart/mixed;/n" . " boundary=/"{$mime_boundary}/""; // multipart boundary $message = "This is a multi-part message in MIME format./n/n" . "--{$mime_boundary}/n" . "Content-Type: text/html; charset=/"iso-8859-1/"/n" . "Content-Transfer-Encoding: 7bit/n/n" . $message . "/n/n"; $message .= "--{$mime_boundary}/n";

    Las líneas en los mensajes de correo electrónico están separadas por secuencias CRLF ( /r/n ). No está claro si la función mail() convierte /n en /r/n o no, pero teniendo en cuenta que sus encabezados From: y Bcc: están usando /r/n , estos probablemente deberían usar lo mismo. Su salida también indica que las terminaciones de línea pueden faltar o estar mal formadas.

    Del manual de PHP :

    Si no se reciben mensajes, intente usar un LF (/ n) solamente. Algunos agentes de transferencia de correo de Unix (más notablemente »qmail ) reemplazan LF por CRLF automáticamente (lo que lleva a duplicar CR si se usa CRLF). Esto debería ser un último recurso, ya que no cumple con »RFC 2822 .
  • Sintaxis de encabezado

    $message .= "Content-Type: {/"application/octet-stream/"};/n" . " name=/"$files[$x]/"/n" .

    Elimina los corchetes y las comillas:

    $message .= "Content-Type: application/octet-stream/n" . " name=/"$files[$x]/"/n" .

    Además, el parámetro de name ha quedado en desuso en favor del parámetro de filename de filename en el encabezado Content-Disposition . Si desea mantenerlo por alguna compatibilidad con versiones anteriores, debe eliminar la ruta. (Su salida indica que está usando tmp_name lugar de name ).

  • Delimitadores

    $message .= "--{$mime_boundary}/n"; // preparing attachments for($x=0;$x<count($files);$x++){ ... $message .= /* body part */; $message .= "--{$mime_boundary}/n"; }

    Tenga en cuenta que el delimitador final debe tener dos guiones finales. Inserte los delimitadores divisorios al comienzo del bucle y agregue un delimitador cercano después del bucle:

    // preparing attachments for($x=0;$x<count($files);$x++){ $message .= "--{$mime_boundary}/n"; ... $message .= /* body part */; } $message .= "--{$mime_boundary}--/n";

    Consulte la sección sobre sintaxis de correo electrónico a continuación.

  • Longitudes de linea

    $k = 100; ... while($i<$count){ $bcc .= $toEmails[$i].","; if($j==$k || $i==$count-1){ ... $headers .= "Bcc:". $bcc . "/r/n";

    Tenga en cuenta que hay límites de longitud de línea en los mensajes de correo electrónico. RFC 5322 :

    ... Each line of characters MUST be no more than 998 characters, and SHOULD be no more than 78 characters, excluding the CRLF.

    Es posible que desee reducir el Bcc su Bcc o introducir FWS (espacio en blanco plegable) :

    $bcc .= $toEmails[$i].",/r/n "; /* FWS */

  • Otros asuntos

    Algunos problemas o avisos adicionales que pueden o no ser útiles:

    foreach($_FILES[''uploadEmail''][''error''] as $key=>$value){ if(!$_FILES[''uploadEmail''][''error''][$key]){

    La última línea es la misma que:

    if(!$value){

    $target_path = ""; $target_path = $target_path . basename( $_FILES[''uploadEmail''][''name''][$key]);

    Supongo que $target_path debe inicializarse en un directorio de carga.

    $toEmails = explode(",",$_POST[''toEmail'']);

    En general, no debe permitir que usuarios aleatorios proporcionen direcciones de correo electrónico salientes, pero sospecho que esta es una aplicación interna para usuarios de confianza.

Sintaxis de correo electrónico

Este es un extracto de cómo se ve la estructura de un cuerpo de mensaje de varias partes de acuerdo con RFC 2046. (Sintaxis BNF, algo simplificada).

multipart-body := [preamble CRLF] dash-boundary CRLF body-part *encapsulation close-delimiter [CRLF epilogue] dash-boundary := "--" boundary body-part := MIME-part-headers [CRLF *OCTET] encapsulation := delimiter CRLF body-part delimiter := CRLF dash-boundary close-delimiter := delimiter "--"

Referencias


Propongo usar PHPMailer para enviar correos con PHPMailer :

<?php require ''PHPMailerAutoload.php''; // If this file is not located in the same directory, use __DIR__ . "/path/to/PHPMailerAutoload.php" $mail = new PHPMailer; $mail->From = ''[email protected]''; $mail->FromName = ''Mailer''; $mail->addAddress(''[email protected]'', ''Joe User''); // Add a recipient $mail->addAddress(''[email protected]''); // Name is optional $mail->addReplyTo(''[email protected]'', ''Information''); $mail->addCC(''[email protected]''); $mail->addBCC(''[email protected]''); $mail->addAttachment(''/var/tmp/file.tar.gz''); // Add attachments $mail->addAttachment(''/tmp/image.jpg'', ''new.jpg''); // Optional name $mail->isHTML(true); // Set email format to HTML $mail->Subject = ''Here is the subject''; $mail->Body = ''This is the HTML message body <b>in bold!</b>''; $mail->AltBody = ''This is the body in plain text for non-HTML mail clients''; if(!$mail->send()) { echo ''Message could not be sent.''; echo ''Mailer Error: '' . $mail->ErrorInfo; } else { echo ''Message has been sent''; } ?>

Descarga y documentación: PHPMailer .