248

I need to send a pdf with mail, is it possible?

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

What am I missing?

  • 17
    To send an attachment with `mail()` function is way harder than you expect, for the sake of your time, try to use [PHPMailer](http://code.google.com/a/apache-extras.org/p/phpmailer/) – Mihai Iorga Sep 06 '12 at 13:38
  • 1
    Or you could just link to it? –  Sep 06 '12 at 13:39
  • @mihai lorga Doesn't that require server side install? If it's possibible without any extensions or plugins, I need to know how. –  Sep 06 '12 at 13:39
  • Quick Google search - http://webcheatsheet.com/php/send_email_text_html_attachment.php – Mark Sep 06 '12 at 13:40
  • @navnav not an option, because space is limited. –  Sep 06 '12 at 13:40
  • 2
    @ChristianNikkanen it's just an well set script, It also has a lot of features that are hard to accomplish. Why to reinvent the wheel? It does not use any additional plugins. – Mihai Iorga Sep 06 '12 at 13:42
  • I have no idea of how to set that script up, and because I'm only automatically sending mails with the same content, I would prefer easier option... –  Sep 06 '12 at 13:50
  • @ChristianNikkanen What do you mean by 'space? Character space, or actual disk space? If it's just a char limit, use a URL trimmer's API. A disk space limit here would not be a problem, though. –  Sep 06 '12 at 14:02
  • It's the diskspace. A 100 MT of diskspace would be full pretty soon... –  Sep 06 '12 at 14:13

16 Answers16

340

I agree with @MihaiIorga in the comments – use the PHPMailer script. You sound like you're rejecting it because you want the easier option. Trust me, PHPMailer is the easier option by a very large margin compared to trying to do it yourself with PHP's built-in mail() function. PHP's mail() function really isn't very good.

To use PHPMailer:

  • Download the PHPMailer script from here: http://github.com/PHPMailer/PHPMailer
  • Extract the archive and copy the script's folder to a convenient place in your project.
  • Include the main script file -- require_once('path/to/file/class.phpmailer.php');

Now, sending emails with attachments goes from being insanely difficult to incredibly easy:

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

$email = new PHPMailer();
$email->SetFrom('you@example.com', 'Your Name'); //Name is optional
$email->Subject   = 'Message Subject';
$email->Body      = $bodytext;
$email->AddAddress( 'destinationaddress@example.com' );

$file_to_attach = 'PATH_OF_YOUR_FILE_HERE';

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

return $email->Send();

It's just that one line $email->AddAttachment(); -- you couldn't ask for any easier.

If you do it with PHP's mail() function, you'll be writing stacks of code, and you'll probably have lots of really difficult to find bugs.

Travis
  • 360
  • 4
  • 17
SDC
  • 14,192
  • 2
  • 35
  • 48
  • Really? That easy? I looked at the file and I couldn't understand a thing. I'll try it. –  Sep 06 '12 at 15:05
  • 1
    Yes, that easy. the whole point of phpMailer is that it does the complex stuff so you don't have to. That's why it's complex to read. Even for sending simply text-only emails, I prefer phpMailer to `mail()`, but for working with attachments it's an absolute no brainer. – SDC Sep 06 '12 at 15:41
  • Do I have to replace `$file_to_attach` with something? Because it's not adding any files. –  Sep 06 '12 at 16:00
  • @SDC: That looks great. My requirement is to generate a PDF on-the-fly and send it as attachment. I have done that using `mail()` function. It works perfectly for mails sent to **GMail**. The mail sent to **Hotmail** have complete encoded PDF in email body itself. For **Yahoo! Mail**, it only receives subject, nothing else. Other domain specific emails just stand no where. FYI, I am generating PDF on-the-fly using **FPDF**. Can I achieve this? – Kumar Kush Jan 25 '13 at 06:16
  • I looked for its documentation. It says I can do that using `AddStringAttachment()` function. That is used for strings, BLOBs and images stored in database itself. I forgot mentioning earlier that the PDFs that I am generating have images embedded also. In that case, the function doesn't seem solve the problem. Meanwhile, I am going to try the code and see how it behaves. – Kumar Kush Jan 25 '13 at 06:40
  • 1
    @kush.impetus - Yes it is possible to generate a file on the fly and then attach it to the mail using phpMailer. I hope you manage to achieve it, but if you have problems, I would suggest asking a fresh question about it, because it's not so easy to provide code examples in this comments section. Easier to start a new question and new answers. :) – SDC Jan 25 '13 at 09:02
  • 6
    I was the same - wanted to use mail() just because I already had it in my code. PHPMAILER took me less than 5 minutes to getting send attachments! – James Wilson Dec 12 '13 at 10:28
  • 9
    PHPMAILER might seem a nice easy way for many. But using it requires to needlessly import another thing to trust (i.e no bugs/etc in the PHPMailer). To not blindly trust one would require one to look at the at least 3155 lines sloc (115.456 kb) of code. Given the alternative purely mail() using answers this seems like a worse tradeoff. The alternative answers can do with less then 100 sloc. Dislike that the answer for "I want A" is answered with "No, use B its better". The other answers tell "A is done like this". – humanityANDpeace Mar 09 '14 at 17:21
  • 133
    I found this question looking for an answer how to use the `mail()` function to add attachments. This answer does not help me do that. – Cypher Jun 09 '14 at 21:02
  • 23
    This isn't the answer to the question. How to send an attachment with PHPMailer isn't how to send an attachment with PHP's mail() which is what is asked. – Toby Aug 06 '14 at 01:54
  • 6
    This answer also ignores the license used by the project. By using PHPMailer, you must be sure that you exclude the package from your source to prevent issues with its LGPL license. – Axle Mar 16 '15 at 18:58
  • @humanityANDpeace You already "blindly trust" the developers of PHP not to provide you with insecure code. At least with something like PHPMailer, you already know how to read the source. – Blazemonger Jun 17 '15 at 20:50
  • The chances of you introducing bugs and errors by rolling your own email are massively higher than by using PHPMailer. The reason that using `mail` properly is difficult is that email is fiendishly complicated, controlled by dozens of overlapping and conflicting RFCs, and `mail` gives you absolutely zero help to get through them. That's why pretty much every `mail` example you see is wrong. Use a library that has gone to the effort of figuring it out - PHPMailer has over 100 million users. Describing how to do attachments without it would take pages and pages to describe. – Synchro Jul 30 '16 at 07:09
  • I added the "use PHPMailer" else it gives an error that the class is not found – matthy Feb 02 '18 at 15:55
  • The PHP mail function is essentially broken and should not be used. SMTP to localhost is both faster and safer, but you can't do that with the mail function. – Synchro Oct 31 '18 at 12:42
  • Could you please update 'PATH_OF_YOUR_FILE_HERE' with and example. I was putting only the path, without the file name and extension. On another website I found that there must be the full path and filename with extension. It took me unnecessarily time. – elano7 Jan 20 '20 at 00:05
  • 2
    If someone asks you about Bing; you don't say forget it just use Google.. – talha2k Feb 22 '21 at 23:25
  • @humanityANDpeace that is to say that I can blindly trust MY own code lol – JorensM Dec 03 '21 at 08:36
  • I downvoted because the OP asked clearly how to send a mail with attachment in *PHP*, not how to do that using 3rd party stuff with the additional hassle of learning some API. I really see no reason why one can't do that easily with the mail() function – elena Jul 02 '22 at 11:41
224

You can try using the following code:

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

    $mailto = 'mail@mail.com';
    $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 <test@test.com>" . $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() );
    }

Edit 14-June-2018

for more readability in some of email provider use

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

Pragnesh Chauhan
  • 8,363
  • 9
  • 42
  • 53
  • $uid seems to be unused. – Edd Jun 06 '14 at 11:02
  • Someone pointed out in [an answer that should be a comment](http://stackoverflow.com/review/late-answers/6318526) that since the OP's code says `'Example message with html'`, then Content-Type should be `text/html` rather than `text/plain`. I'm posting the comment on his behalf since he doesn't have enough rep to post comments and I've flagged the answer for deletion. – Adi Inbar Nov 25 '14 at 22:09
  • in this code, do you have to define $path and $filename? And would it be something like $filename = $_FILES['userfile']['tmp_name']; ? – malfy Mar 19 '15 at 20:05
  • Why do you declare `$file` after referencing it in `$filename`? – Kellen Stuart Apr 01 '17 at 23:09
  • 2
    From PHPMailer's docs... "Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules - the vast majority of code that you'll find online that uses the mail() function directly is just plain wrong!" ...it's true! I've used something like this answer to send mail with attachments and it worked! Only to find a few days later that while Gmail shows the attachments just fine, other providers show the base64 content directly inline in the mail. – Aaron Cicali Jun 13 '18 at 20:55
  • I was getting "sendmail: command failed: 550 5.7.1 Delivery not authorized, message refused: Message is not RFC 2822 compliant". I had to remove these lines to fix it: $headers .= "Content-Transfer-Encoding: 7bit" . $eol; $headers .= "This is a MIME encoded message." . $eol; – Jon Marnock Jun 22 '18 at 02:31
  • The code posted in this answer will work for a subset of cases, but it omits a ton of requirements surrounding encoding, line folding, character sets and much more that may cause problems for both senders and receivers. Formatting for email is *hard*. – Synchro Oct 31 '18 at 13:37
  • `$headers .= "Content-Transfer-Encoding: 7bit" . $eol;` was breaking my emails until I changed it to `$headers .= "Content-Transfer-Encoding: 8bit" . $eol;` – Blue Eyed Behemoth Feb 18 '19 at 00:55
  • @Pragnesh Chauhan I had tried your script can you please check my question https://stackoverflow.com/q/58129139/9004424 – Husna Sep 28 '19 at 06:30
  • it all worked except HTML format and when i changed "plain" to html in this line, it worked fine $body .= "Content-Type: text/plain; charset=\"iso-8859-1\"" . $eol; @pragnesh, you should update this line – Naveed Metlo Apr 21 '20 at 16:50
  • 1
    the text body is missing only attachment is sent – Zaheer Jul 23 '20 at 09:41
  • @user3197473, what have you passed in a message section? – Pragnesh Chauhan Jul 24 '20 at 09:38
  • 1
    This script was sending an empty file before I replaced this line `"$body .= "Content-Disposition: attachment" . $eol;"` by this one : `$body .= 'Content-Disposition: attachment; name=\"". $filename.";'.$eol.$eol;` – rilent Dec 17 '20 at 13:54
  • Couldn't get this to work - message body missing, attached file shows 414 bytes in email client but 0kb on disk and opening with text editor shows no content. (The next answer, by Simon Mokhele, looks similar but worked for me). – youcantryreachingme Dec 17 '20 at 21:48
154

For PHP 5.5.27 security update

$file = $path.$filename;
$content = file_get_contents( $file);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$file_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=\"".$file_name."\"\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;
}
Harshil Modi
  • 397
  • 3
  • 8
  • 15
Simon Mokhele
  • 3,913
  • 3
  • 21
  • 22
  • you didnt define $filename. What is it supposed to be? The filepath? – Jon Nov 04 '15 at 16:15
  • 5
    @Jon. $filename, is the actual name of your file and $path is the actual file path without the file name. I thought the variables were descriptive enough to declare and institution them – Simon Mokhele Nov 05 '15 at 07:30
  • its meant to be in a function if you dont want to define them function mail_attachment($filename, $path, $mailto, $from_mail, $from_name, $replyto, $subject, $message) – Jon Nov 05 '15 at 13:58
  • No. Its not meant to be a function. It's meant to be a peace of code that sends an email with an attachment(As you can see the question). Another thing, different developer code differently. Others can choose to make a function and others can choose to just "// Or do something here" instead of returning. – Simon Mokhele Nov 05 '15 at 17:01
  • 5
    Note for those sending multiple attachments - separate MIME parts with `$nmessage .= "--".$uid."\r\n";`, and after the final MIME part, use `$nmessage .= "--".$uid."--";` (as shown above). – rinogo Apr 26 '16 at 21:49
  • 1
    If $message is HTML, it is not parsed and shown as it is, including the HTML tags. How to fix it? – Sunish Menon Apr 29 '16 at 05:25
  • 2
    This finally worked after a headache of trying to get the stupid phpmailer thing to work. – E.Arrowood Aug 23 '16 at 05:54
  • It is missing $nmessage = wordwrap($nmessage,70); .... right before sending it. On several servers you have to wrap the email at around 70 columns... – ZioBit Oct 13 '16 at 03:11
  • 1
    This one actually worked. The accepted answer was not working for me. It would send over the file corrupted. – Webmaster G Nov 21 '16 at 19:54
  • @ZioBit calling wordwrap on the entire $nmessage breaks the attachment name if it is not pretty short. – Stoopkid May 01 '17 at 17:42
  • 1
    It works for me only when i put the double quotes around charset: `"Content-Type:text/plain; charset=\"iso-8859-1\"".$eol` - without quotes, there isn't any error, but the mail will be not sent!!! – deblocker Dec 13 '17 at 16:09
  • What should I do for multiple attachments? – Mike B Apr 25 '18 at 11:11
  • @SimonMokhele Please help me, I am sitting with this for a long time. I am getting the mail attachment, but when open the file, I am not able to read the file. Please see the posted Question: https://stackoverflow.com/questions/50167626/unable-to-read-php-mail-attachment –  May 04 '18 at 11:59
  • how if i didn't have $path and just fetching from user and directly sent. – Bhautik Sep 24 '18 at 10:34
  • It worked..Btu Mail comes in spam folder..why is it so?How can i get it to inbox? – affaz Nov 30 '18 at 17:48
  • @Simon Mokhele I had to implement your script attachment working fine other fields not working can you please go through my question https://stackoverflow.com/q/57743898/9004424 – Husna Sep 02 '19 at 07:10
  • It's not working for me. Oddly the function basename is not doing anything. The result is the same as the argument. $filename = basename("C:\Users\Meier\Desktop\Misc Photos and Pictures\Tiger Woods theme.jpg"); Also, the attachment I receive in the email is empty. – M610 Oct 11 '19 at 18:01
  • 1
    Note for those using the mail function on a Unix/Linux machine: the headers should be separated by _just_ "\n" instead of "\r\n". Using \r\n resulted in only the first header being recognized, everything else was just dumped into the body of the email. – Brendan D. Oct 28 '19 at 16:53
  • Is using $uid = md5(uniqid(time())) still acceptable with latest guidance on 'md5' ? Is there a better way to generate a unique $uid? – Rick Hellewell Nov 08 '19 at 23:41
  • 2
    This is a very clear and clean answer. It works when received by Outlook, Gmail alike. Neat answer. If you can update with HTML message part, this will become more complete. – Sriram Nadiminti Jun 19 '21 at 13:58
22

Swiftmailer is another easy-to-use script that automatically protects against email injection and makes attachments a breeze. I also strongly discourage using PHP's built-in mail() function.

To use:

  • Download Swiftmailer, and place the lib folder in your project
  • Include the main file using require_once 'lib/swift_required.php';

Now add the code when you need to mail:

// Create the message
$message = Swift_Message::newInstance()
    ->setSubject('Your subject')
    ->setFrom(array('webmaster@mysite.com' => 'Web Master'))
    ->setTo(array('receiver@example.com'))
    ->setBody('Here is the message itself')
    ->attach(Swift_Attachment::fromPath('myPDF.pdf'));

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

More information and options can be found in the Swiftmailer Docs.

Matthew Johnson
  • 4,875
  • 2
  • 38
  • 51
  • 6
    cause you offer to dwonload 3rd-party library, I guess – vladkras Nov 27 '15 at 13:16
  • Is PHPMailer not 3rd-party ? or mean @MatthewJohnson made or is part of the maintners of swiftmailer ? either ways as long as the solution is good and effective, a downvote would be unappropriate... – Xsmael Dec 17 '18 at 15:40
  • 1
    @Xsmael, PHPMailer is definitely 3rd party :) I disagree with the downvotes, as (at least at the time) the solution does work. However, people can vote however they wish, and the upvotes more than negate the downs. – Matthew Johnson Dec 19 '18 at 15:16
17

To send an email with attachment we need to use the multipart/mixed MIME type that specifies that mixed types will be included in the email. Moreover, we want to use multipart/alternative MIME type to send both plain-text and HTML version of the email.Have a look at the example:

<?php 
//define the receiver of the email 
$to = 'youraddress@example.com'; 
//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: webmaster@example.com\r\nReply-To: webmaster@example.com"; 
//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"; 
?>

As you can see, sending an email with attachment is easy to accomplish. In the preceding example we have multipart/mixed MIME type, and inside it we have multipart/alternative MIME type that specifies two versions of the email. To include an attachment to our message, we read the data from the specified file into a string, encode it with base64, split it in smaller chunks to make sure that it matches the MIME specifications and then include it as an attachment.

Taken from here.

Basith
  • 1,077
  • 7
  • 22
  • 15
    copy/paste of the content in the link I added in OP comments – Mark Sep 06 '12 at 13:42
  • Good snippet, though I had to provide an extra newline after the boundary string in order to make it work. I'm guessing it has something to do with the line endings of the php file. My editor defaults to LF, but I think the standard expects a carriage return aswell (CRLF). – Ogier Schelvis Dec 06 '18 at 09:49
13

This works for me. It also attaches multiple attachments too. easily

<?php

if ($_POST && isset($_FILES['file'])) {
    $recipient_email = "recipient@yourmail.com"; //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
  • 4,783
  • 4
  • 18
  • 27
  • This code is vulnerable to header injection attacks due to the lack of validation & appropriate contextual escaping of user input. – Synchro Oct 31 '18 at 13:41
  • @Synchro .. this is the only code I find for multiple attachments which worked for me .. can you please suggest how to use this in secure manner . – NMathur Jan 02 '19 at 08:07
7

After struggling for a while with badly formatted attachments, this is the code I used:

$email = new PHPMailer();
$email->From      = 'from@somedomain.com';
$email->FromName  = 'FromName';
$email->Subject   = 'Subject';
$email->Body      = 'Body';
$email->AddAddress( 'to@somedomain.com' );
$email->AddAttachment( "/path/to/filename.ext" , "filename.ext", 'base64', 'application/octet-stream' );
$email->Send();
Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268
7

None of the above answers worked for me due to their specified attachment format (application/octet-stream). Use application/pdf for best results with PDF files.

<?php

// just edit these 
$to          = "email1@domain.com, email2@domain.com"; // addresses to email pdf to
$from        = "sent_from@domain.com"; // 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
  • 8,064
  • 8
  • 37
  • 50
  • $headers = "From: $from$eolMIME-Version: 1.0$eol" keeps throwing an undefined variable error on $eolMIME. – Recoil Feb 21 '20 at 20:53
  • hmm... replace `"From: $from$eolMIME-Version: 1.0$eol"` with `"From: $from" . "$eolMIME-Version: 1.0$eol"` – omikes Feb 21 '20 at 22:12
  • maybe it wont let you add two variables in like that in some versions of php, it worked on the one i was using. sorry about that. in fact there are so many occurrences you might want to replace all instances of `$eol` with `" . "$eol` that way its all done in one fell swoop. – omikes Feb 21 '20 at 22:16
6

Working Concept :

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
  • 5,670
  • 2
  • 44
  • 39
3

HTML Code:

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

PHP Code:

<?php
if($_POST['button']){
{
    //Server Variables
    $server_name = "Your Name";
    $server_mail = "your_mail@domain.com";

    //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
  • 772
  • 1
  • 8
  • 31
1

I ended up writing my own email sending/encoding function. This has worked well for me for sending PDF attachments. I have not used the other features in production.

Note: Despite the spec being quite emphatic that you must use \r\n to separate headers, I found it only worked when I used PHP_EOL. I have only tested this on 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' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        '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' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        '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' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        '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' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        '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' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        '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' => 'noreply@foo.com',
#        'to' => 'jason@jasonwoof.com',
#        '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
  • 4,176
  • 1
  • 19
  • 28
  • I just realized that my code called some functions that I didn't include. They just made sure that to/from/cc/etc values were legit. I removed them, and now this code works as is, by itself. – JasonWoof May 06 '17 at 23:25
1
            $to = "to@gmail.com";
            $subject = "Subject Of The Mail";
            $message = "Hi there,<br/><br/>This is my message.<br><br>";

            $headers = "From: From-Name<from@gmail.com>";
// 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
  • 450
  • 3
  • 6
0

you can send regular or attachment emails using this class that I created.

here is the link with examples of how to use it.

https://github.com/Nerdtrix/EZMAIL

jerryurenaa
  • 3,863
  • 1
  • 27
  • 17
0
ContactRequestSubmitted

Name:'.$name.'

Email:'.$email.'

Subject:'.$subject.'

Message:
'.$message.'

';$headers="From:$fromName"."";if(!empty($uploadedFile)&&file_exists($uploadedFile)){$semi_rand=md5(time());$mime_boundary="==Multipart_Boundary_x{$semi_rand}x";$headers.="\nMIME-Version:1.0\n"."Content-Type:multipart/mixed;\n"."boundary=\"{$mime_boundary}\"";$message="--{$mime_boundary}\n"."Content-Type:text/html;charset=\"UTF-8\"\n"."Content-Transfer-Encoding:7bit\n\n".$htmlContent."\n\n";if(is_file($uploadedFile)){$message.="--{$mime_boundary}\n";$fp=@fopen($uploadedFile,"rb");$data=@fread($fp,filesize($uploadedFile));@fclose($fp);$data=chunk_split(base64_encode($data));$message.="Content-Type:application/octet-stream;name=\"".basename($uploadedFile)."\"\n"."Content-Description:".basename($uploadedFile)."\n"."Content-Disposition:attachment;\n"."filename=\"".basename($uploadedFile)."\";size=".filesize($uploadedFile).";\n"."Content-Transfer-Encoding:base64\n\n".$data."\n\n";}$message.="--{$mime_boundary}--";$returnpath="-f".$email;$mail=mail($toEmail,$emailSubject,$message,$headers,$returnpath);@unlink($uploadedFile);}else{$headers.="\r\n"."MIME-Version:1.0";$headers.="\r\n"."Content-type:text/html;charset=UTF-8";$mail=mail($toEmail,$emailSubject,$htmlContent,$headers);}if($mail){$statusMsg='Yourcontactrequesthasbeensubmittedsuccessfully!';$msgClass='succdiv';$postData='';}else{$statusMsg='Yourcontactrequestsubmissionfailed,pleasetryagain.';}}}}else{$statusMsg='Pleasefillallthefields.';}}?>">"placeholder="Name"required="">"placeholder="Emailaddress"required="">"placeholder="Subject"required="">[Source][1]

https://www.findinall.com/blog/how-to-test-mail-and-send-attachment-in-mail/

-1

100% working Concept to send email with attachment in 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 = "info@companyname.com";  // GMAIL username
  $mail->Password = "mailPassword";          // GMAIL password

  $mail->SetFrom('info@companyname.com', 'new application submitted');
  $mail->AddReplyTo("name@yourdomain.com","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 = 'info@companyname.com';
  $mail->AddAddress($address, "companyname");

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

  if (!$mail->Send()) {
    /* Error */
    echo 'Message not Sent! Email at info@companyname.com';
  } else {
    /* Success */
    echo 'Sent Successfully! <b> Check your Mail</b>';
  }
}

I used this code for google smtp mail sending with Attachment....

Note: Download PHPMailer Library from here -> https://github.com/PHPMailer/PHPMailer

Irshad Khan
  • 5,670
  • 2
  • 44
  • 39
-2

Copying the code from this page - works in mail()

He starts off my making a function mail_attachment that can be called later. Which he does later with his attachment code.

<?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 = "my@mail.com";
$my_replyto = "my_reply_to@mail.net";
$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, "recipient@mail.org", $my_mail, $my_name, $my_replyto, $my_subject, $my_message);
?>

He has more details on his page and answers some problems in the comments section.

Jon
  • 6,437
  • 8
  • 43
  • 63