Tuesday, July 28, 2009

Attaching to email a file uploaded in a form

I had to create a processing script that would attach to an e-mail the file a user uploaded through a contact-us style form. After more digging than I expected (most scripts simply upload the file to the server and leave it there; I wanted it e-mailed as an attachment) I found this script, which did exactly what I wanted, except that it allowed just one attachment. My solution had to have up to three attachments, and also accommodate more fields than just the comments textbox (i.e. phone, address, etc.).

Well, I must say this script laid much of the groundwork. With a few modifications I was able to get it to exactly what I needed. Hopefully these tips will help you, too...

Include additional fields
The way I did this was to first add the fields in the form, e.g.

Phone: <' input name="phone" type="text">

And so on for each field I wanted to add.

Then, in the processing script, I edited line 11:
$message = $_POST['message'];

To include any other fields I wanted to include in the message, e.g.

$message = 'Phone: ' . $_POST['phone'] . "\n" . 'Message: ' . $_POST['message'];

The plain text - Phone: - is what you want to appear in the e-mail next to the input. Not necessary but certainly convenient. Within the $_POST brackets put the input name in single quotes.

There's probably a more efficient way to loop through all the form fields and compile them into the message, but since I only had 4-5 fields I figured this would be the least time-consuming way.

Multiple file attachments
To add more attachments I first added them in the form, e.g.

<' input name="fileatt2" type="file">

Then in the processing script I defined all the variables for each file, e.g.

$fileatt2 = $_FILES['fileatt2']['tmp_name'];
$fileatt_type2 = $_FILES['fileatt2']['type'];
$fileatt_name2 = $_FILES['fileatt2']['name'];

I put these immediately after the first file's variables (beginning on line 17), although I don't think the order should matter.

Then, just under line 43, which reads:

$data = chunk_split(base64_encode($data));

I added the following code:

if (is_uploaded_file($fileatt2)) {
// Read the file to be attached ('rb' = read binary)
$file2 = fopen($fileatt2,'rb');
$data2 = fread($file2,filesize($fileatt2));
fclose($file2);
$data2 = chunk_split(base64_encode($data2));

$message .= "--{$mime_boundary}\n" .
"Content-Type: {$fileatt_type2};\n" .
" name=\"{$fileatt_name2}\"\n" .
//"Content-Disposition: attachment;\n" .
//" filename=\"{$fileatt_name2}\"\n" .
"Content-Transfer-Encoding: base64\n\n" .
$data2;

}

Which is really just a duplicate of the code for the first file, except for the closing mime-boundary. Of course, you should edit the variable names - $file, $data, $fileatt_name and so on.

Putting this just before the first file ensures that both are included in the message - otherwise you'll just get the first file attached. So, for any additional attachment fields you're adding, you should add the code in an order reversed from the one they appear in the form. For example for a third field, you'd add the same code with $fileatt3 but it would come before the code for $fileatt2.

Again, there's probably a more efficient way to loop through all the fields automatically, but I only had three so writing that would be too time-consuming - so for most standard forms, this should do.

2 comments:

  1. I too am a self taught web and graphic designer. Nice to see others too! I will be following your work on here, so don't ever think you are posting for nothing. Thanks for the tips and I will send you some of mine sometime if you are interested.

    ReplyDelete
  2. Thanks for following! Yeah definitely feel free to share any input or other knowledge :)

    ReplyDelete