Upload more than one file from form

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
relief8
Forum Newbie
Posts: 13
Joined: Fri Jan 25, 2008 4:28 pm

Upload more than one file from form

Post by relief8 »

Hi,

I am using the code below to process a form file field that sends the uploaded file as an attachment in an email. Does anyone know how to edit this code so that I can upload and attach more than one file?Thanks in advance

Code: Select all

 
//Create attachment
 
   // generate a random string to be used as the boundary marker
   $mime_boundary="==Multipart_Boundary_x".md5(mt_rand())."x";
 
   // store the file information to variables for easier access
   $tmp_name = $_FILES['filename']['tmp_name'];
   $type = $_FILES['filename']['type'];
   $name = $_FILES['filename']['name'];
   $size = $_FILES['filename']['size'];
 
   // if the upload succeded, the file will exist
   if (file_exists($tmp_name)){
 
      // check to make sure that it is an uploaded file and not a system file
      if(is_uploaded_file($tmp_name)){
 
         // open the file for a binary read
         $file = fopen($tmp_name,'rb');
 
         // read the file content into a variable
         $data = fread($file,filesize($tmp_name));
 
         // close the file
         fclose($file);
 
         // now we encode it and split it into acceptable length lines
         $data = chunk_split(base64_encode($data));
     }
 
      // now we'll build the message headers
      $headers = "From: $from\r\n" .
         "MIME-Version: 1.0\r\n" .
         "Content-Type: multipart/mixed;\r\n" .
         " boundary=\"{$mime_boundary}\"";
 
      // next, we'll build the message body
      // note that we insert two dashes in front of the
      // MIME boundary when we use it
      $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";
 
      // now we'll insert a boundary to indicate we're starting the attachment
      // we have to specify the content type, file name, and disposition as
      // an attachment, then add the file content and set another boundary to
      // indicate that the end of the file has been reached
      $message .= "--{$mime_boundary}\n" .
         "Content-Type: {$type};\n" .
         " name=\"{$name}\"\n" .
         //"Content-Disposition: attachment;\n" .
         //" filename=\"{$fileatt_name}\"\n" .
         "Content-Transfer-Encoding: base64\n\n" .
         $data . "\n\n" .
         "--{$mime_boundary}--\n";
 
      // now we just send the message
      if (@mail($to, $subject, $message, $headers))
         echo "Message Sent";
      else
         echo "Failed to send";
   }
}
 
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Re: Upload more than one file from form

Post by jayshields »

Put more than one input of type file in your HTML form. Probably be good to go with an array of inputs, for example named "filename[]". then you can handle them by doing something like you've already got but with a foreach loop on the 'filename' index of the $_FILES array.
relief8
Forum Newbie
Posts: 13
Joined: Fri Jan 25, 2008 4:28 pm

Re: Upload more than one file from form

Post by relief8 »

Hmmm, I think this might be a little over my head. Any chance you could give me a sample?
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Re: Upload more than one file from form

Post by jayshields »

Code: Select all

<form enctype="multipart/form-data">
<input type="file" name="filename[]" />
<input type="file" name="filename[]" />
<input type="file" name="filename[]" />
<input type="file" name="filename[]" />
<input type="file" name="filename[]" />
<input type="submit" name="submit" />
</form>

Code: Select all

if(isset($_POST['submit']))
{
  foreach($_FILES['filename'] as $file)
  {
    $tmp_name = $file['tmp_name'];
    $type = $file['type'];
    $name = $file['name'];
    $size = $file['size'];
    
    //Do whatever you want
  }
}
 
As for the email attachment section, I'm not sure, using something like SwiftMailer would provide an easier solution.
relief8
Forum Newbie
Posts: 13
Joined: Fri Jan 25, 2008 4:28 pm

Re: Upload more than one file from form

Post by relief8 »

Ok, so I changed the input type file fields to look like this:

Code: Select all

 
<input type="file" name="filename[]"/>
 
Then changed my php page to look like this:

Code: Select all

 
//Create attachment
 
   // generate a random string to be used as the boundary marker
   $mime_boundary="==Multipart_Boundary_x".md5(mt_rand())."x";
 
   // store the file information to variables for easier access
 foreach($_FILES['filename'] as $fileb) {
   $tmp_name = $_FILES['fileb']['tmp_name'];
   $type = $_FILES['fileb']['type'];
   $name = $_FILES['fileb']['name'];
   $size = $_FILES['fileb']['size'];
 
   // if the upload succeded, the file will exist
   if (file_exists($tmp_name)){
 
      // check to make sure that it is an uploaded file and not a system file
      if(is_uploaded_file($tmp_name)){
 
         // open the file for a binary read
         $file = fopen($tmp_name,'rb');
 
         // read the file content into a variable
         $data = fread($file,filesize($tmp_name));
 
         // close the file
         fclose($file);
    }
 
         // now we encode it and split it into acceptable length lines
         $data = chunk_split(base64_encode($data));
     }
 
      // now we'll build the message headers
      $headers = "From: $from\r\n" .
         "MIME-Version: 1.0\r\n" .
         "Content-Type: multipart/mixed;\r\n" .
         " boundary=\"{$mime_boundary}\"";
 
      // next, we'll build the message body
      // note that we insert two dashes in front of the
      // MIME boundary when we use it
      $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";
 
      // now we'll insert a boundary to indicate we're starting the attachment
      // we have to specify the content type, file name, and disposition as
      // an attachment, then add the file content and set another boundary to
      // indicate that the end of the file has been reached
      $message .= "--{$mime_boundary}\n" .
         "Content-Type: {$type};\n" .
         " name=\"{$name}\"\n" .
         //"Content-Disposition: attachment;\n" .
         //" filename=\"{$fileatt_name}\"\n" .
         "Content-Transfer-Encoding: base64\n\n" .
         $data . "\n\n" .
         "--{$mime_boundary}--\n";
 
      // now we just send the message
      if (@mail($to, $subject, $message, $headers))
         echo "Your message has been sent.  Thank you for the order.";
      else
         echo "Failed to send";
   }
}
 
Now when I press submit I get 5 emails sent with different browser attachments and not the file attachments.

Any thoughts???
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Re: Upload more than one file from form

Post by jayshields »

Apart from it being hideously wrong in principle anyway (as I said, I don't know about multiple attachment email headers, I recommend using a library/class to sort that out for you - like SwiftMailer), you aren't referencing the foreach variable properly.

You need to change this

Code: Select all

 foreach($_FILES['filename'] as $fileb) {
    $tmp_name = $_FILES['fileb']['tmp_name'];
    $type = $_FILES['fileb']['type'];
    $name = $_FILES['fileb']['name'];
    $size = $_FILES['fileb']['size'];
to this

Code: Select all

 foreach($_FILES['filename'] as $fileb) {
    $tmp_name = $fileb['tmp_name'];
    $type = $fileb['type'];
    $name = $fileb['name'];
    $size = $fileb['size'];
I thought I made that clear in my example, but anyway, if you change it to that you should be getting somewhere with the file uploads, but the email attachments are a different problem.
Post Reply