Enviar anexos com PHP Mail ()?

224

Preciso enviar um pdf com correio, é possível?

$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);

o que estou perdendo?


fonte
16
Para enviar um anexo com mail()função é muito mais difícil do que o esperado, por causa de seu tempo, tente usar PHPMailer
Mihai Iorga
1
Ou você pode simplesmente criar um link para ele?
@mihai lorga Isso não requer instalação no servidor? Se for possível sem extensões ou plugins, preciso saber como.
Pesquisa rápida no Google - webcheatsheet.com/php/send_email_text_html_attachment.php
Marque
2
@ChristianNikkanen é apenas um script bem definido, também possui muitos recursos difíceis de realizar. Por que reinventar a roda? Ele não usa nenhum plug-in adicional.
Mihai Iorga

Respostas:

310

Eu concordo com @MihaiIorga nos comentários - use o script PHPMailer. Parece que você está rejeitando porque deseja a opção mais fácil. Confie em mim, o PHPMailer é a opção mais fácil por uma margem muito grande em comparação com tentar fazer você mesmo com a mail()função interna do PHP . A mail()função do PHP realmente não é muito boa.

Para usar o PHPMailer:

  • Faça o download do script PHPMailer aqui: http://github.com/PHPMailer/PHPMailer
  • Extraia o arquivo morto e copie a pasta do script para um local conveniente no seu projeto.
  • Inclua o arquivo de script principal - require_once('path/to/file/class.phpmailer.php');

Agora, enviar e-mails com anexos deixa de ser incrivelmente difícil e incrivelmente 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();

É apenas uma linha $email->AddAttachment();- você não poderia pedir mais fácil.

Se você fizer isso com a mail()função do PHP , estará escrevendo pilhas de código e provavelmente terá muitos problemas realmente difíceis de encontrar.

SDC
fonte
1
Sim, é fácil. o ponto principal do phpMailer é que ele faz coisas complexas para que você não precise. É por isso que é complexo ler. Mesmo para enviar e-mails apenas com texto, eu prefiro o phpMailer mail(), mas para trabalhar com anexos é absolutamente óbvio.
SDC
4
Eu era o mesmo - queria usar mail () só porque já o tinha no meu código. O PHPMAILER levou menos de 5 minutos para receber os anexos!
James Wilson
109
Encontrei esta pergunta procurando uma resposta sobre como usar a mail()função para adicionar anexos. Esta resposta não me ajuda a fazer isso.
Cypher
19
Esta não é a resposta para a pergunta. Como enviar um anexo com o PHPMailer não é como enviar um anexo com o mail () do PHP, o que é solicitado.
Toby
4
Essa resposta também ignora a licença usada pelo projeto. Ao usar o PHPMailer, você deve excluir o pacote da sua fonte para evitar problemas com a licença LGPL.
Eixo
191

Você pode tentar usar o seguinte 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 de junho de 2018

para maior legibilidade em parte do uso do provedor de email

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

Pragnesh Chauhan
fonte
$ uid parece não ser usado.
Edd
Alguém apontou em uma resposta que deve ser um comentário que desde que o código do OP diz 'Example message with <b>html</b>', então Content-Type deve ser text/html, em vez de text/plain. Estou postando o comentário em seu nome, pois ele não tem representante suficiente para postar comentários e sinalizei a resposta para exclusão.
Adi Inbar
nesse código, você precisa definir $ path e $ filename? E seria algo como $ filename = $ _FILES ['userfile'] ['tmp_name']; ?
malfy
Por que você declara $filedepois de fazer referência a ele $filename?
Kolob Canyon
2
Dos documentos do PHPMailer ... "A formatação de emails corretamente é surpreendentemente difícil. Existem inúmeras RFCs sobrepostas, exigindo uma aderência estrita a regras de formatação e codificação terrivelmente complicadas - a grande maioria do código que você encontra on-line que usa diretamente a função mail () é simplesmente errado! " ...é verdade! Usei algo como esta resposta para enviar e-mails com anexos e funcionou! Apenas alguns dias depois, apesar de o Gmail mostrar os anexos, outros provedores mostram o conteúdo da base64 diretamente embutido no e-mail.
Aaron Cicali
134

Para atualização de segurança do 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
fonte
você não definiu $ filename. O que isso deveria ser? O caminho do arquivo?
Jon Jon
3
@Jon. $ filename, é o nome real do seu arquivo e $ path é o caminho do arquivo real, sem o nome do arquivo. Eu pensei que as variáveis foram descritivo o suficiente para declarar e instituição los
Simon Mokhele
seu significado é estar em uma função se você não quiser defini-los como função mail_attachment ($ filename, $ path, $ mailto, $ from_mail, $ from_name, $ replyto, $ subject, $ message)
Jon
3
Nota para aqueles que enviam vários anexos - separe as partes MIME com $nmessage .= "--".$uid."\r\n";e após a parte final MIME, use $nmessage .= "--".$uid."--";(como mostrado acima).
Rinogo 26/04
2
Isso finalmente funcionou após uma dor de cabeça ao tentar fazer com que a coisa idiota do phpmailer funcionasse.
E.Arrowood
22

O Swiftmailer é outro script fácil de usar que protege automaticamente contra a injeção de e- mails e facilita a anexação. Também desencorajo fortemente o uso do PHP embutidomail() função.

Usar:

  • Faça o download do Swiftmailer e coloque olib pasta no seu projeto
  • Inclua o arquivo principal usando require_once 'lib/swift_required.php';

Agora adicione o código quando precisar enviar por email:

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

Mais informações e opções podem ser encontradas nos documentos do Swiftmailer .

Matthew Johnson
fonte
6
causar-lhe oferecer aos dwonload biblioteca de 3-parte, eu acho
vladkras
O PHPMailer não é de terceiros? ou significa @MatthewJohnson fez ou faz parte dos mantenedores do swiftmailer? Ou maneiras, desde que a solução é boa e eficaz, uma downvote seria unappropriate ...
Xsmael
1
@Xsmael, o PHPMailer é definitivamente um terceiro :) Não concordo com os votos negativos, pois (pelo menos na época) a solução funciona. No entanto, as pessoas podem votar da maneira que desejarem, e os votos positivos mais do que negam os baixos.
Matthew Johnson
17

Para enviar um email com anexo, precisamos usar o tipo MIME multipart / misto que especifica que os tipos mistos serão incluídos no email. Além disso, queremos usar o tipo MIME multipart / alternativo para enviar a versão em texto sem formatação e HTML do email.Veja o exemplo:

<?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 você pode ver, é fácil enviar um email com anexo. No exemplo anterior, temos o tipo MIME multipart / misto e, dentro dele, temos o tipo MIME multipart / alternativo que especifica duas versões do email. Para incluir um anexo em nossa mensagem, lemos os dados do arquivo especificado em uma string, codificamos com base64, dividimos em pedaços menores para garantir que correspondam às especificações MIME e os incluímos como anexo.

Tomado daqui .

Basith
fonte
15
copiar / colar do conteúdo do link eu adicionei em comentários OP
Mark
Bom snippet, embora eu tivesse que fornecer uma nova linha extra após a cadeia de limite para fazê-la funcionar. Eu estou supondo que tem algo a ver com as terminações de linha do arquivo php. Meu editor padrão é LF, mas acho que o padrão espera um retorno de carro também (CRLF).
Ogier Schelvis
9

Isso funciona para mim. Também anexa vários anexos também. facilmente

<?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
fonte
Esse código é vulnerável a ataques de injeção de cabeçalho devido à falta de validação e escape contextual apropriado da entrada do usuário.
Synchro
@ Synchro .. este é o único código que encontro para vários anexos que funcionou para mim .. você pode sugerir como usar isso de maneira segura.
NMathur
7

Depois de lutar por um tempo com anexos mal formatados, este é o código que eu usei:

$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
fonte
6

Conceito de trabalho:

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
fonte
6

Nenhuma das respostas acima funcionou para mim devido ao formato de anexo especificado ( application/octet-stream). Use application/pdfpara obter melhores resultados com arquivos 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
fonte
$ headers = "From: $ from $ eolMIME-Version: 1.0 $ eol" continua gerando um erro variável indefinido no $ eolMIME.
Recoil
hmm ... substitua "From: $from$eolMIME-Version: 1.0$eol"por"From: $from" . "$eolMIME-Version: 1.0$eol"
omikes 21/02
talvez não permita que você adicione duas variáveis ​​assim em algumas versões do php, funcionou na que eu estava usando. me desculpe por isso. de fato, existem tantas ocorrências que você pode querer substituir todas as instâncias $eolpor " . "$eoldessa maneira, tudo é feito de uma só 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
fonte
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
fonte
1

Acabei escrevendo minha própria função de envio / codificação de email. Isso funcionou bem para mim no envio de anexos em PDF. Eu não usei os outros recursos na produção.

Nota: Apesar de as especificações serem bastante enfáticas que você deve usar \ r \ n para separar os cabeçalhos, achei que só funcionava quando usei o PHP_EOL. Eu só testei isso no 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
fonte
Acabei de perceber que meu código chamava algumas funções que não incluí. Eles apenas se certificaram de que os valores de / para / cc / etc eram legítimos. Eu os removi e agora esse código funciona como está, por si só.
JasonWoof
-1

Copiar o código desta página - funciona no mail ()

Ele começa a criar uma função mail_attachment que pode ser chamada mais tarde. O que ele faz mais tarde com seu código de anexo.

<?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);
?>

Ele tem mais detalhes em sua página e responde a alguns problemas na seção de comentários.

Jon
fonte
-1

Conceito 100% funcional para enviar email com anexo em 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>';
  }
}

Eu usei esse código para o envio de e-mail do smtp do Google com anexo ....

Nota: Baixe a Biblioteca PHPMailer aqui -> https://github.com/PHPMailer/PHPMailer

Irshad Khan
fonte