PHP mail with Multiple Attachments

In previous example we've learned how to send PHP mail with an attachment, and I have also created separate Ajax tutorial for the same. But some of you also want to send multiple attachments, so today I am going to refine the PHP code to show you how we can send multiple attachments with PHP mail.

Markup

First we need to create HTML multipart/form-data form with file input fields. Multiple PHP attachments You can turn those file fields into associative arrays using square brackets as shown below, or add attribute multiple="multiple" in file input tag. this way no matter how many fields we add, we can simply iterate each field and access their variables later. Have a look at HTML form code below :
HTML
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
<form method="post" action="send_attachments.php" enctype="multipart/form-data"> <label> <span>Your Name</span> <input type="text" value="Jon Snow" name="s_name" /> </label> <label> <span>Your Email</span> <input type="email" value="" name="s_email" /> </label> <label> <span>Message</span> <textarea name="s_message"></textarea> </label> <label> <span>Attachments</span> <!-- File input fields, you can add as many as required--> <input type="file" name="file[]" /> <input type="file" name="file[]" /> <input type="file" name="file[]" /> <!-- OR --> <! -- <input type="file" name="file[]" multiple="multiple" /> --> </label> <label> <input type="submit" value="Send" /> </label> </form>
This is basic HTML form, it's not pretty right now but you can always make it better using different CSS styles to it, and using JavaScript you can also add-remove fields dynamically.

PHP Mail

Once you are done with HTML part, you can examine the code below and copy it in a file and name it as send_attachments.php, which is the PHP file pointed in action parameter in HTML form above.
PHP
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
<?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("sanwebe.com"); 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.'); } } ?>
The PHP code simply iterates though uploaded files, creates base64 encoded strings and combines them in single mail body encapsulated in boundaries.That's it, the PHP script now should send multiple attachments. If you encounter any error during file upload, you may need to set the value of upload_max_filesize and post_max_size in your php.ini, because it determines the size of file you can upload.
Check-out Ajax Contact Form with an Attachment for Ajax tutorial.
Download
  • Thank you for this excellent script - among all the many other scripts which I tried, and which claimed to be able to send multiple attachments, yours is the only one which is sufficiently robust to be adapted for use on a variety of contact forms - it works both with and without attachments - brilliant !
  • Hi,
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    $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($firstname)); $body .= chunk_split(base64_encode($lastname)); $body .= chunk_split(base64_encode($email)); $body .= chunk_split(base64_encode($phonenumber)); $body .= chunk_split(base64_encode($visa));
    The 4th line which says $visa is outputting garbage value. If I add anyother field in place of visa it shows garbage value. I am following the same process you have mentioned above please respond I am looking for a solution from one mont
  • Thanks for the script!But it has issues and for me it's not working propper, if you haven't selected any file (empty file input fields) -> content is sent base64 encoded ...If you have at least one file selected, it works fine!Any idea???