¿Enviar archivos adjuntos con PHP Mail ()?

224

Necesito enviar un pdf con correo, ¿es posible?

$to = "xxx";
$subject = "Subject" ;
$message = 'Example message with <b>html</b>';
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From: xxx <xxx>' . "\r\n";
mail($to,$subject,$message,$headers);

¿Qué me estoy perdiendo?


fuente
16
Enviar un archivo adjunto con mail()función es mucho más difícil de lo que espera, por el bien de su tiempo, intente usar PHPMailer
Mihai Iorga
1
¿O simplemente podrías vincularlo?
@mihai lorga ¿Eso no requiere instalación del lado del servidor? Si es posible sin extensiones o complementos, necesito saber cómo.
Búsqueda rápida en Google: webcheatsheet.com/php/send_email_text_html_attachment.php
Marque el
2
@ChristianNikkanen es solo un script bien establecido, también tiene muchas características que son difíciles de lograr. ¿Por qué reinventar la rueda? No utiliza ningún complemento adicional.
Mihai Iorga

Respuestas:

310

Estoy de acuerdo con @MihaiIorga en los comentarios: use el script PHPMailer. Parece que lo estás rechazando porque quieres la opción más fácil. Confía en mí, PHPMailer es la opción más fácil por un margen muy grande en comparación con intentar hacerlo tú mismo con la función incorporada de PHP mail(). La mail()función de PHP realmente no es muy buena.

Para usar PHPMailer:

  • Descargue el script PHPMailer desde aquí: http://github.com/PHPMailer/PHPMailer
  • Extraiga el archivo y copie la carpeta del script en un lugar conveniente de su proyecto.
  • Incluya el archivo de script principal: require_once('path/to/file/class.phpmailer.php');

Ahora, enviar correos electrónicos con archivos adjuntos pasa de ser increíblemente difícil a increíblemente fácil:

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$email = new PHPMailer();
$email->SetFrom('[email protected]', 'Your Name'); //Name is optional
$email->Subject   = 'Message Subject';
$email->Body      = $bodytext;
$email->AddAddress( '[email protected]' );

$file_to_attach = 'PATH_OF_YOUR_FILE_HERE';

$email->AddAttachment( $file_to_attach , 'NameOfFile.pdf' );

return $email->Send();

Es solo esa línea $email->AddAttachment();: no podría pedir más fácilmente.

Si lo hace con la mail()función de PHP , estará escribiendo pilas de código, y probablemente tendrá muchos errores realmente difíciles de encontrar.

SDC
fuente
1
Sí, así de fácil. El punto principal de phpMailer es que hace las cosas complejas para que no tenga que hacerlo. Por eso es complejo de leer. Incluso para enviar correos electrónicos de solo texto, prefiero phpMailer mail(), pero para trabajar con archivos adjuntos es absolutamente obvio.
COSUDE
44
Yo era igual: quería usar mail () solo porque ya lo tenía en mi código. ¡PHPMAILER me tomó menos de 5 minutos para recibir los archivos adjuntos!
James Wilson
109
Encontré esta pregunta buscando una respuesta sobre cómo usar la mail()función para agregar archivos adjuntos. Esta respuesta no me ayuda a hacer eso.
Cypher
19
Esta no es la respuesta a la pregunta. Cómo enviar un archivo adjunto con PHPMailer no es cómo enviar un archivo adjunto con el correo de PHP (), que es lo que se solicita.
Toby
44
Esta respuesta también ignora la licencia utilizada por el proyecto. Al usar PHPMailer, debe asegurarse de excluir el paquete de su fuente para evitar problemas con su licencia LGPL.
Eje
191

Puedes intentar usar el siguiente código:

    $filename = 'myfile';
    $path = 'your path goes here';
    $file = $path . "/" . $filename;

    $mailto = '[email protected]';
    $subject = 'Subject';
    $message = 'My message';

    $content = file_get_contents($file);
    $content = chunk_split(base64_encode($content));

    // a random hash will be necessary to send mixed content
    $separator = md5(time());

    // carriage return type (RFC)
    $eol = "\r\n";

    // main header (multipart mandatory)
    $headers = "From: name <[email protected]>" . $eol;
    $headers .= "MIME-Version: 1.0" . $eol;
    $headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol;
    $headers .= "Content-Transfer-Encoding: 7bit" . $eol;
    $headers .= "This is a MIME encoded message." . $eol;

    // message
    $body = "--" . $separator . $eol;
    $body .= "Content-Type: text/plain; charset=\"iso-8859-1\"" . $eol;
    $body .= "Content-Transfer-Encoding: 8bit" . $eol;
    $body .= $message . $eol;

    // attachment
    $body .= "--" . $separator . $eol;
    $body .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"" . $eol;
    $body .= "Content-Transfer-Encoding: base64" . $eol;
    $body .= "Content-Disposition: attachment" . $eol;
    $body .= $content . $eol;
    $body .= "--" . $separator . "--";

    //SEND Mail
    if (mail($mailto, $subject, $body, $headers)) {
        echo "mail send ... OK"; // or use booleans here
    } else {
        echo "mail send ... ERROR!";
        print_r( error_get_last() );
    }

Editar 14-junio-2018

para mayor legibilidad en algunos de los proveedores de correo electrónico

$body .= $eol . $message . $eol . $eol; y $body .= $eol . $content . $eol . $eol;

Pragnesh Chauhan
fuente
$ uid parece estar sin usar.
Edd
Alguien señaló en una respuesta que debería ser un comentario que, como dice el código del OP 'Example message with <b>html</b>', entonces Content-Type debería ser text/htmlmás que text/plain. Estoy publicando el comentario en su nombre ya que no tiene suficiente representante para publicar comentarios y he marcado la respuesta para su eliminación.
Adi Inbar
en este código, ¿tiene que definir $ path y $ filename? ¿Y sería algo así como $ filename = $ _FILES ['userfile'] ['tmp_name']; ?
mal
¿Por qué declaras $filedespués de hacer referencia a él $filename?
Kolob Canyon
2
De los documentos de PHPMailer ... "Formatear el correo electrónico correctamente es sorprendentemente difícil. Hay innumerables RFC superpuestos, que requieren un estricto cumplimiento de las reglas de codificación y formato horriblemente complicadas, la gran mayoría de código que encontrará en línea que utiliza la función mail () directamente es simplemente incorrecto! " ...¡es verdad! ¡He usado algo como esta respuesta para enviar correos con archivos adjuntos y funcionó! Solo unos días después, si bien Gmail muestra los archivos adjuntos correctamente, otros proveedores muestran el contenido base64 directamente en línea en el correo.
Aaron Cicali
134

Para la actualización de seguridad de PHP 5.5.27

$file = $path.$filename;
$content = file_get_contents( $file);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);

// header
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";

// message & attachment
$nmessage = "--".$uid."\r\n";
$nmessage .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$nmessage .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$nmessage .= $message."\r\n\r\n";
$nmessage .= "--".$uid."\r\n";
$nmessage .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
$nmessage .= "Content-Transfer-Encoding: base64\r\n";
$nmessage .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$nmessage .= $content."\r\n\r\n";
$nmessage .= "--".$uid."--";

if (mail($mailto, $subject, $nmessage, $header)) {
    return true; // Or do something here
} else {
  return false;
}
Simon Mokhele
fuente
no definiste $ filename. ¿Qué se supone que es? El filepath?
Jon
3
@Jon. $ filename, es el nombre real de su archivo y $ path es la ruta real del archivo sin el nombre del archivo. Pensé que las variables eran lo suficientemente descriptivas como para declararlas e instituirlas
Simon Mokhele
está destinado a estar en una función si no desea definirlas función mail_attachment ($ filename, $ path, $ mailto, $ from_mail, $ from_name, $ replyto, $ subject, $ message)
Jon
3
Nota para aquellos que envían múltiples archivos adjuntos: separe las partes MIME con $nmessage .= "--".$uid."\r\n";, y después de la parte MIME final, use $nmessage .= "--".$uid."--";(como se muestra arriba).
rinogo
2
Esto finalmente funcionó después de un dolor de cabeza de tratar de hacer que el estúpido phpmailer funcione.
E.Arrowood el
22

Swiftmailer es otro script fácil de usar que protege automáticamente contra la inyección de correo electrónico y hace que los archivos adjuntos sean muy fáciles . También desaconsejo firmemente el uso de PHP incorporadomail() .

Usar:

  • Descargue Swiftmailer y coloque la libcarpeta en su proyecto
  • Incluya el archivo principal usando require_once 'lib/swift_required.php';

Ahora agregue el código cuando necesite enviar un correo:

// Create the message
$message = Swift_Message::newInstance()
    ->setSubject('Your subject')
    ->setFrom(array('[email protected]' => 'Web Master'))
    ->setTo(array('[email protected]'))
    ->setBody('Here is the message itself')
    ->attach(Swift_Attachment::fromPath('myPDF.pdf'));

//send the message          
$mailer->send($message);

Se puede encontrar más información y opciones en los documentos de Swiftmailer .

Matthew Johnson
fuente
66
porque ofreces cargar dwonload biblioteca de terceros, supongo
vladkras
¿PHPMailer no es de terceros? o significa que @MatthewJohnson hizo o es parte de los mantenedores de swiftmailer? De cualquier manera, siempre que la solución sea buena y efectiva, un
voto negativo
1
@Xsmael, PHPMailer es definitivamente un tercero :) No estoy de acuerdo con los votos negativos, ya que (al menos en ese momento) la solución funciona. Sin embargo, las personas pueden votar como quieran, y los votos positivos más que negar los negativos.
Matthew Johnson
17

Para enviar un correo electrónico con datos adjuntos, debemos usar el tipo MIME multiparte / mixto que especifica que los tipos mixtos se incluirán en el correo electrónico. Además, queremos usar el tipo MIME multiparte / alternativo para enviar versiones de texto sin formato y HTML del correo electrónico. Eche un vistazo al ejemplo:

<?php 
//define the receiver of the email 
$to = '[email protected]'; 
//define the subject of the email 
$subject = 'Test email with attachment'; 
//create a boundary string. It must be unique 
//so we use the MD5 algorithm to generate a random hash 
$random_hash = md5(date('r', time())); 
//define the headers we want passed. Note that they are separated with \r\n 
$headers = "From: [email protected]\r\nReply-To: [email protected]"; 
//add boundary string and mime type specification 
$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\""; 
//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents('attachment.zip'))); 
//define the body of the message. 
ob_start(); //Turn on output buffering 
?> 
--PHP-mixed-<?php echo $random_hash; ?>  
Content-Type: multipart/alternative; boundary="PHP-alt-<?php echo $random_hash; ?>" 

--PHP-alt-<?php echo $random_hash; ?>  
Content-Type: text/plain; charset="iso-8859-1" 
Content-Transfer-Encoding: 7bit

Hello World!!! 
This is simple text email message. 

--PHP-alt-<?php echo $random_hash; ?>  
Content-Type: text/html; charset="iso-8859-1" 
Content-Transfer-Encoding: 7bit

<h2>Hello World!</h2> 
<p>This is something with <b>HTML</b> formatting.</p> 

--PHP-alt-<?php echo $random_hash; ?>-- 

--PHP-mixed-<?php echo $random_hash; ?>  
Content-Type: application/zip; name="attachment.zip"  
Content-Transfer-Encoding: base64  
Content-Disposition: attachment  

<?php echo $attachment; ?> 
--PHP-mixed-<?php echo $random_hash; ?>-- 

<?php 
//copy current buffer contents into $message variable and delete current output buffer 
$message = ob_get_clean(); 
//send the email 
$mail_sent = @mail( $to, $subject, $message, $headers ); 
//if the message is sent successfully print "Mail sent". Otherwise print "Mail failed" 
echo $mail_sent ? "Mail sent" : "Mail failed"; 
?>

Como puede ver, enviar un correo electrónico con archivo adjunto es fácil de lograr. En el ejemplo anterior, tenemos el tipo MIME multiparte / mixto, y dentro tenemos el tipo MIME multiparte / alternativo que especifica dos versiones del correo electrónico. Para incluir un archivo adjunto a nuestro mensaje, leemos los datos del archivo especificado en una cadena, lo codificamos con base64, lo dividimos en fragmentos más pequeños para asegurarnos de que coincida con las especificaciones MIME y luego lo incluimos como archivo adjunto.

Tomado de aquí .

Basith
fuente
15
copiar / pegar el contenido en el enlace que agregué en los comentarios de OP
Marque el
Buen fragmento, aunque tuve que proporcionar una nueva línea adicional después de la cadena de límite para que funcione. Supongo que tiene algo que ver con las terminaciones de línea del archivo php. Mi editor está predeterminado en LF, pero creo que el estándar también espera un retorno de carro (CRLF).
Ogier Schelvis
9

Esto funciona para mi. También adjunta múltiples archivos adjuntos también. fácilmente

<?php

if ($_POST && isset($_FILES['file'])) {
    $recipient_email = "[email protected]"; //recepient
    $from_email = "info@your_domain.com"; //from email using site domain.
    $subject = "Attachment email from your website!"; //email subject line

    $sender_name = filter_var($_POST["s_name"], FILTER_SANITIZE_STRING); //capture sender name
    $sender_email = filter_var($_POST["s_email"], FILTER_SANITIZE_STRING); //capture sender email
    $sender_message = filter_var($_POST["s_message"], FILTER_SANITIZE_STRING); //capture message
    $attachments = $_FILES['file'];

    //php validation
    if (strlen($sender_name) < 4) {
        die('Name is too short or empty');
    }
    if (!filter_var($sender_email, FILTER_VALIDATE_EMAIL)) {
        die('Invalid email');
    }
    if (strlen($sender_message) < 4) {
        die('Too short message! Please enter something');
    }

    $file_count = count($attachments['name']); //count total files attached
    $boundary = md5("specialToken$4332"); // boundary token to be used

    if ($file_count > 0) { //if attachment exists
        //header
        $headers = "MIME-Version: 1.0\r\n";
        $headers .= "From:" . $from_email . "\r\n";
        $headers .= "Reply-To: " . $sender_email . "" . "\r\n";
        $headers .= "Content-Type: multipart/mixed; boundary = $boundary\r\n\r\n";

        //message text
        $body = "--$boundary\r\n";
        $body .= "Content-Type: text/plain; charset=ISO-8859-1\r\n";
        $body .= "Content-Transfer-Encoding: base64\r\n\r\n";
        $body .= chunk_split(base64_encode($sender_message));

        //attachments
        for ($x = 0; $x < $file_count; $x++) {
            if (!empty($attachments['name'][$x])) {

                if ($attachments['error'][$x] > 0) { //exit script and output error if we encounter any
                    $mymsg = array(
                        1 => "The uploaded file exceeds the upload_max_filesize directive in php.ini",
                        2 => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
                        3 => "The uploaded file was only partially uploaded",
                        4 => "No file was uploaded",
                        6 => "Missing a temporary folder");
                    die($mymsg[$attachments['error'][$x]]);
                }

                //get file info
                $file_name = $attachments['name'][$x];
                $file_size = $attachments['size'][$x];
                $file_type = $attachments['type'][$x];

                //read file 
                $handle = fopen($attachments['tmp_name'][$x], "r");
                $content = fread($handle, $file_size);
                fclose($handle);
                $encoded_content = chunk_split(base64_encode($content)); //split into smaller chunks (RFC 2045)

                $body .= "--$boundary\r\n";
                $body .= "Content-Type: $file_type; name=" . $file_name . "\r\n";
                $body .= "Content-Disposition: attachment; filename=" . $file_name . "\r\n";
                $body .= "Content-Transfer-Encoding: base64\r\n";
                $body .= "X-Attachment-Id: " . rand(1000, 99999) . "\r\n\r\n";
                $body .= $encoded_content;
            }
        }
    } else { //send plain email otherwise
        $headers = "From:" . $from_email . "\r\n" .
                "Reply-To: " . $sender_email . "\n" .
                "X-Mailer: PHP/" . phpversion();
        $body = $sender_message;
    }

    $sentMail = @mail($recipient_email, $subject, $body, $headers);
    if ($sentMail) { //output success or failure messages
        die('Thank you for your email');
    } else {
        die('Could not send mail! Please check your PHP mail configuration.');
    }
}
?>
Rotimi
fuente
Este código es vulnerable a los ataques de inyección de encabezado debido a la falta de validación y al escape contextual apropiado de la entrada del usuario.
Sincronización
@Synchro ... este es el único código que encuentro para múltiples archivos adjuntos que funcionó para mí ... ¿podría sugerirme cómo usar esto de manera segura?
NMathur
7

Después de luchar por un tiempo con archivos adjuntos mal formateados, este es el código que utilicé:

$email = new PHPMailer();
$email->From      = '[email protected]';
$email->FromName  = 'FromName';
$email->Subject   = 'Subject';
$email->Body      = 'Body';
$email->AddAddress( '[email protected]' );
$email->AddAttachment( "/path/to/filename.ext" , "filename.ext", 'base64', 'application/octet-stream' );
$email->Send();
CONvid19
fuente
6

Concepto de trabajo:

if (isset($_POST['submit'])) {
    $mailto = $_POST["mailTo"];
    $from_mail = $_POST["fromEmail"];
    $replyto = $_POST["fromEmail"];
    $from_name = $_POST["fromName"];
    $message = $_POST["message"];
    $subject = $_POST["subject"];

    $filename = $_FILES["fileAttach"]["name"];
    $content = chunk_split(base64_encode(file_get_contents($_FILES["fileAttach"]["tmp_name"])));

    $uid = md5(uniqid(time()));
    $name = basename($file);
    $header = "From: " . $from_name . " <" . $from_mail . ">\r\n";
    $header .= "Reply-To: " . $replyto . "\r\n";

    $header .= "MIME-Version: 1.0\r\n";
    $header .= "Content-Type: multipart/mixed; boundary=\"" . $uid . "\"\r\n\r\n";
    $header .= "This is a multi-part message in MIME format.\r\n";
    $header .= "--" . $uid . "\r\n";

// You add html "Content-type: text/html; charset=utf-8\n" or for Text "Content-type:text/plain; charset=iso-8859-1\r\n" by I.khan
    $header .= "Content-type:text/html; charset=utf-8\n";
    $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";

// User Message you can add HTML if You Selected HTML content
    $header .= "<div style='color: red'>" . $message . "</div>\r\n\r\n";

    $header .= "--" . $uid . "\r\n";
    $header .= "Content-Type: application/octet-stream; name=\"" . $filename . "\"\r\n"; // use different content types here
    $header .= "Content-Transfer-Encoding: base64\r\n";
    $header .= "Content-Disposition: attachment; filename=\"" . $filename . "\"\r\n\r\n"; // For Attachment
    $header .= $content . "\r\n\r\n";
    $header .= "--" . $uid . "--";
    if (mail($mailto, $subject, "", $header)) {
        echo "<script>alert('Success');</script>"; // or use booleans here
    } else {
        echo "<script>alert('Failed');</script>";
    }
}
Irshad Khan
fuente
6

Ninguna de las respuestas anteriores funcionó para mí debido a su formato de archivo adjunto especificado ( application/octet-stream). Úselo application/pdfpara obtener mejores resultados con archivos PDF.

<?php

// just edit these 
$to          = "[email protected], [email protected]"; // addresses to email pdf to
$from        = "[email protected]"; // address message is sent from
$subject     = "Your PDF email subject"; // email subject
$body        = "<p>The PDF is attached.</p>"; // email body
$pdfLocation = "./your-pdf.pdf"; // file location
$pdfName     = "pdf-file.pdf"; // pdf file name recipient will get
$filetype    = "application/pdf"; // type

// creates headers and mime boundary
$eol = PHP_EOL;
$semi_rand     = md5(time());
$mime_boundary = "==Multipart_Boundary_$semi_rand";
$headers       = "From: $from$eolMIME-Version: 1.0$eol" .
    "Content-Type: multipart/mixed;$eol boundary=\"$mime_boundary\"";

// add html message body
$message = "--$mime_boundary$eol" .
    "Content-Type: text/html; charset=\"iso-8859-1\"$eol" .
    "Content-Transfer-Encoding: 7bit$eol$eol$body$eol";

// fetches pdf
$file = fopen($pdfLocation, 'rb');
$data = fread($file, filesize($pdfLocation));
fclose($file);
$pdf = chunk_split(base64_encode($data));

// attaches pdf to email
$message .= "--$mime_boundary$eol" .
    "Content-Type: $filetype;$eol name=\"$pdfName\"$eol" .
    "Content-Disposition: attachment;$eol filename=\"$pdfName\"$eol" .
    "Content-Transfer-Encoding: base64$eol$eol$pdf$eol--$mime_boundary--";

// Sends the email
if(mail($to, $subject, $message, $headers)) {
    echo "The email was sent.";
}
else {
    echo "There was an error sending the mail.";
}
omikes
fuente
$ headers = "From: $ from $ eolMIME-Version: 1.0 $ eol" sigue arrojando un error variable indefinido en $ eolMIME.
Retroceso
hmm ... reemplazar "From: $from$eolMIME-Version: 1.0$eol"con"From: $from" . "$eolMIME-Version: 1.0$eol"
omikes
tal vez no te permita agregar dos variables como esa en algunas versiones de php, funcionó en la que estaba usando. Lo siento por eso. de hecho, hay tantas ocurrencias es posible que desee reemplazar todas las instancias $eolde " . "$eolesa manera todo está hecho de una sola vez.
omikes
2
            $to = "[email protected]";
            $subject = "Subject Of The Mail";
            $message = "Hi there,<br/><br/>This is my message.<br><br>";

            $headers = "From: From-Name<[email protected]>";
// 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";
                $filepath = 'uploads/'.$_FILES['image']['name'];
                move_uploaded_file($_FILES['image']['tmp_name'], $filepath); //upload the file
                $filename = $_FILES['image']['name'];
                $file = fopen($filepath, "rb");
                $data = fread($file, filesize($filepath));
                fclose($file);
                $data = chunk_split(base64_encode($data));
                $message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$filename\"\n" .
                        "Content-Disposition: attachment;\n" . " filename=\"$filename\"\n" .
                        "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
                $message .= "--{$mime_boundary}\n";

mail($to, $subject, $message, $headers);
Dhawal Naik
fuente
2

Código HTML:

<form enctype="multipart/form-data" method="POST" action=""> 
    <label>Your Name <input type="text" name="sender_name" /> </label> 
    <label>Your Email <input type="email" name="sender_email" /> </label> 
    <label>Your Contact Number <input type="tel" name="contactnumber" /> </label>
    <label>Subject <input type="text" name="subject" /> </label> 
    <label>Message <textarea name="description"></textarea> </label> 
    <label>Attachment <input type="file" name="attachment" /></label> 
    <label><input type="submit" name="button" value="Submit" /></label> 
</form> 

Código PHP:

<?php
if($_POST['button']){
{
    //Server Variables
    $server_name = "Your Name";
    $server_mail = "[email protected]";

    //Name Attributes of HTML FORM
    $sender_email = "sender_email";
    $sender_name = "sender_name";
    $contact = "contactnumber";
    $mail_subject = "subject";
    $input_file = "attachment";
    $message = "description";

    //Fetching HTML Values
    $sender_name = $_POST[$sender_name];
    $sender_mail = $_POST[$sender_email];
    $message = $_POST[$message];
    $contact= $_POST[$contact];
    $mail_subject = $_POST[$mail_subject];

    //Checking if File is uploaded
    if(isset($_FILES[$input_file])) 
    { 
        //Main Content
        $main_subject = "Subject seen on server's mail";
        $main_body = "Hello $server_name,<br><br> 
        $sender_name ,contacted you through your website and the details are as below: <br><br> 
        Name : $sender_name <br> 
        Contact Number : $contact <br> 
        Email : $sender_mail <br> 
        Subject : $mail_subject <br> 
        Message : $message.";

        //Reply Content
        $reply_subject = "Subject seen on sender's mail";
        $reply_body = "Hello $sender_name,<br> 
        \t Thank you for filling the contact form. We will revert back to you shortly.<br><br>
        This is an auto generated mail sent from our Mail Server.<br>
        Please do not reply to this mail.<br>
        Regards<br>
        $server_name";

//#############################DO NOT CHANGE ANYTHING BELOW THIS LINE#############################
        $filename= $_FILES[$input_file]['name'];
        $file = chunk_split(base64_encode(file_get_contents($_FILES[$input_file]['tmp_name'])));
        $uid = md5(uniqid(time()));
        //Sending mail to Server
        $retval = mail($server_mail, $main_subject, "--$uid\r\nContent-type:text/html; charset=iso-8859-1\r\nContent-Transfer-Encoding: 7bit\r\n\r\n $main_body \r\n\r\n--$uid\r\nContent-Type: application/octet-stream; name=\"$filename\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"$filename\"\r\n\r\n$file\r\n\r\n--$uid--", "From: $sender_name <$sender_mail>\r\nReply-To: $sender_mail\r\nMIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"$uid\"\r\n\r\n");
        //Sending mail to Sender
        $retval = mail($sender_mail, $reply_subject, $reply_body , "From: $server_name<$server_mail>\r\nMIME-Version: 1.0\r\nContent-type: text/html\r\n");
//#############################DO NOT CHANGE ANYTHING ABOVE THIS LINE#############################

        //Output
        if ($retval == true) {
            echo "Message sent successfully...";
            echo "<script>window.location.replace('index.html');</script>";
        } else {
            echo "Error<br>";
            echo "Message could not be sent...Try again later";
            echo "<script>window.location.replace('index.html');</script>";
        }
    }else{
        echo "Error<br>";
        echo "File Not Found";
    }
}else{
    echo "Error<br>";
    echo "Unauthorised Access";
}
Ebenezer Isaac
fuente
1

Terminé escribiendo mi propia función de envío / codificación de correo electrónico. Esto me ha funcionado bien para enviar archivos adjuntos en PDF. No he usado las otras características en producción.

Nota: A pesar de que la especificación es bastante enfática en que debe usar \ r \ n para separar los encabezados, descubrí que solo funcionaba cuando usaba PHP_EOL. Solo he probado esto en Linux. YMMV

<?php
# $args must be an associative array
#     required keys: from, to, body
#          body can be a string or a [tree of] associative arrays. See examples below
#     optional keys: subject, reply_to, cc, bcc
# EXAMPLES:
#    # text-only email:
#    email2(array(
#        'from' => '[email protected]',
#        'to' => '[email protected]',
#        'subject' => 'test',
#        # body will be text/plain because we're passing a string that doesn't start with '<'
#        'body' => 'Hi, testing 1 2 3',
#    ));
#
#    # html-only email
#    email2(array(
#        'from' => '[email protected]',
#        'to' => '[email protected]',
#        'subject' => 'test',
#        # body will be text/html because we're passing a string that starts with '<'
#        'body' => '<h1>Hi!</h1>I like <a href="http://cheese.com">cheese</a>',
#    ));
#
#    # text-only email (explicitly, in case first character is dynamic or something)
#    email2(array(
#        'from' => '[email protected]',
#        'to' => '[email protected]',
#        'subject' => 'test',
#        # body will be text/plain because we're passing a string that doesn't start with '<'
#        'body' => array(
#            'type' => 'text',
#            'body' => $message_text,
#        )
#    ));
#
#    # email with text and html alternatives (auto-detected mime types)
#    email2(array(
#        'from' => '[email protected]',
#        'to' => '[email protected]',
#        'subject' => 'test',
#        'body' => array(
#            'type' => 'alternatives',
#            'body' => array(
#                "Hi!\n\nI like cheese",
#                '<h1>Hi!</h1><p>I like <a href="http://cheese.com">cheese</a></p>',
#            )
#        )
#    ));
#
#    # email with text and html alternatives (explicit types)
#    email2(array(
#        'from' => '[email protected]',
#        'to' => '[email protected]',
#        'subject' => 'test',
#        'body' => array(
#            'type' => 'alternatives',
#            'body' => array(
#                array(
#                    'type' => 'text',
#                    'body' => "Hi!\n\nI like cheese",
#                ),
#                array(
#                    'type' => 'html',
#                    'body' => '<h1>Hi!</h1><p>I like cheese</p>',
#                ),
#            )
#        )
#    ));
#
#    # email with an attachment
#    email2(array(
#        'from' => '[email protected]',
#        'to' => '[email protected]',
#        'subject' => 'test',
#        'body' => array(
#            'type' => 'mixed',
#            'body' => array(
#                "Hi!\n\nCheck out this (inline) image",
#                array(
#                    'type' => 'image/png',
#                    'disposition' => 'inline',
#                    'body' => $image_data, # raw file contents
#                ),
#                "Hi!\n\nAnd here's an attachment",
#                array(
#                    'type' => 'application/pdf; name="attachment.pdf"',
#                    'disposition' => 'attachment; filename="attachment.pdf"',
#                    'body' => $pdf_data, # raw file contents
#                ),
#                "Or you can use shorthand:",
#                array(
#                    'type' => 'application/pdf',
#                    'attachment' => 'attachment.pdf', # name for client (not data source)
#                    'body' => $pdf_data, # raw file contents
#                ),
#            )
#        )
#    ))
function email2($args) {
    if (!isset($args['from'])) { return 1; }
    $from = $args['from'];
    if (!isset($args['to'])) { return 2; }
    $to = $args['to'];
    $subject = isset($args['subject']) ? $args['subject'] : '';
    $reply_to = isset($args['reply_to']) ? $args['reply_to'] : '';
    $cc = isset($args['cc']) ? $args['cc'] : '';
    $bcc = isset($args['bcc']) ? $args['bcc'] : '';

    #FIXME should allow many more characters here (and do Q encoding)
    $subject = isset($args['subject']) ? $args['subject'] : '';
    $subject = preg_replace("|[^a-z0-9 _/#'.:&,-]|i", '_', $subject);

    $headers = "From: $from";
    if($reply_to) {
        $headers .= PHP_EOL . "Reply-To: $reply_to";
    }
    if($cc) {
        $headers .= PHP_EOL . "CC: $cc";
    }
    if($bcc) {
        $headers .= PHP_EOL . "BCC: $bcc";
    }

    $r = email2_helper($args['body']);
    $headers .= PHP_EOL . $r[0];
    $body = $r[1];

    if (mail($to, $subject, $body, $headers)) {
        return 0;
    } else {
        return 5;
    }
}

function email2_helper($body, $top = true) {
    if (is_string($body)) {
        if (substr($body, 0, 1) == '<') {
            return email2_helper(array('type' => 'html', 'body' => $body), $top);
        } else {
            return email2_helper(array('type' => 'text', 'body' => $body), $top);
        }
    }
    # now we can assume $body is an associative array
    # defaults:
    $type = 'application/octet-stream';
    $mime = false;
    $boundary = null;
    $disposition = null;
    $charset = false;
    # process 'type' first, because it sets defaults for others
    if (isset($body['type'])) {
        $type = $body['type'];
        if ($type === 'text') {
            $type = 'text/plain';
            $charset = true;
        } elseif ($type === 'html') {
            $type = 'text/html';
            $charset = true;
        } elseif ($type === 'alternative' || $type === 'alternatives') {
            $mime = true;
            $type = 'multipart/alternative';
        } elseif ($type === 'mixed') {
            $mime = true;
            $type = 'multipart/mixed';
        }
    }
    if (isset($body['disposition'])) {
        $disposition = $body['disposition'];
    }
    if (isset($body['attachment'])) {
        if ($disposition == null) {
            $disposition = 'attachment';
        }
        $disposition .= "; filename=\"{$body['attachment']}\"";
        $type .= "; name=\"{$body['attachment']}\"";
    }
    # make headers
    $headers = array();
    if ($top && $mime) {
        $headers[] = 'MIME-Version: 1.0';
    }
    if ($mime) {
        $boundary = md5('5sd^%Ca)~aAfF0=4mIN' . rand() . rand());
        $type .= "; boundary=$boundary";
    }
    if ($charset) {
        $type .= '; charset=' . (isset($body['charset']) ? $body['charset'] : 'UTF-8');
    }
    $headers[] = "Content-Type: $type";
    if ($disposition !== null) {
        $headers[] = "Content-Disposition: {$disposition}";
    }

    $data = '';
    # return array, first el is headers, 2nd is body (php's mail() needs them separate)
    if ($mime) {
        foreach ($body['body'] as $sub_body) {
            $data .= "--$boundary" . PHP_EOL;
            $r = email2_helper($sub_body, false);
            $data .= $r[0] . PHP_EOL . PHP_EOL; # headers
            $data .= $r[1] . PHP_EOL . PHP_EOL; # body
        }
        $data .= "--$boundary--";
    } else {
        if(preg_match('/[^\x09\x0A\x0D\x20-\x7E]/', $body['body'])) {
            $headers[] = "Content-Transfer-Encoding: base64";
            $data .= chunk_split(base64_encode($body['body']));
        } else {
            $data .= $body['body'];
        }
    }
    return array(join(PHP_EOL, $headers), $data);
}
JasonWoof
fuente
Me acabo de dar cuenta de que mi código llamaba a algunas funciones que no incluí. Solo se aseguraron de que los valores de / desde / cc / etc. fueran legítimos. Los eliminé, y ahora este código funciona como está, solo.
JasonWoof
-1

Copiar el código de esta página - funciona en mail ()

Él comienza a hacer una función mail_attachment que se puede llamar más tarde. Lo que hace más tarde con su código de archivo adjunto.

<?php
function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) {
    $file = $path.$filename;
    $file_size = filesize($file);
    $handle = fopen($file, "r");
    $content = fread($handle, $file_size);
    fclose($handle);
    $content = chunk_split(base64_encode($content));
    $uid = md5(uniqid(time()));
    $header = "From: ".$from_name." <".$from_mail.">\r\n";
    $header .= "Reply-To: ".$replyto."\r\n";
    $header .= "MIME-Version: 1.0\r\n";
    $header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
    $header .= "This is a multi-part message in MIME format.\r\n";
    $header .= "--".$uid."\r\n";
    $header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
    $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
    $header .= $message."\r\n\r\n";
    $header .= "--".$uid."\r\n";
    $header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use different content types here
    $header .= "Content-Transfer-Encoding: base64\r\n";
    $header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
    $header .= $content."\r\n\r\n";
    $header .= "--".$uid."--";
    if (mail($mailto, $subject, "", $header)) {
        echo "mail send ... OK"; // or use booleans here
    } else {
        echo "mail send ... ERROR!";
    }
}

//start editing and inputting attachment details here
$my_file = "somefile.zip";
$my_path = "/your_path/to_the_attachment/";
$my_name = "Olaf Lederer";
$my_mail = "[email protected]";
$my_replyto = "[email protected]";
$my_subject = "This is a mail with attachment.";
$my_message = "Hallo,\r\ndo you like this script? I hope it will help.\r\n\r\ngr. Olaf";
mail_attachment($my_file, $my_path, "[email protected]", $my_mail, $my_name, $my_replyto, $my_subject, $my_message);
?>

Tiene más detalles en su página y responde algunos problemas en la sección de comentarios.

Jon
fuente
-1

Concepto 100% funcional para enviar correos electrónicos con archivos adjuntos en php:

if (isset($_POST['submit'])) {
  extract($_POST);
  require_once('mail/class.phpmailer.php');

  $subject = "$name Applied For - $position";
  $email_message = "<div>Thanks for Applying ....</div> ";

  $mail = new PHPMailer;
  $mail->IsSMTP(); // telling the class to use SMTP
  $mail->Host = "mail.companyname.com"; // SMTP server
  $mail->SMTPDebug = 0;
  $mail->SMTPAuth = true;
  $mail->SMTPSecure = "ssl";
  $mail->Host = "smtp.gmail.com";
  $mail->Port = 465;
  $mail->IsHTML(true);
  $mail->Username = "[email protected]";  // GMAIL username
  $mail->Password = "mailPassword";          // GMAIL password

  $mail->SetFrom('[email protected]', 'new application submitted');
  $mail->AddReplyTo("[email protected]","First Last");
  $mail->Subject = "your subject";

  $mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test

  $mail->MsgHTML($email_message);

  $address = '[email protected]';
  $mail->AddAddress($address, "companyname");

  $mail->AddAttachment($_FILES['file']['tmp_name'], $_FILES['file']['name']);      // attachment

  if (!$mail->Send()) {
    /* Error */
    echo 'Message not Sent! Email at [email protected]';
  } else {
    /* Success */
    echo 'Sent Successfully! <b> Check your Mail</b>';
  }
}

Utilicé este código para el envío de correo smtp de google con Adjunto ...

Nota: Descargue la biblioteca PHPMailer desde aquí -> https://github.com/PHPMailer/PHPMailer

Irshad Khan
fuente