Solved

php email attachment

Posted on 2011-09-24
36
220 Views
Last Modified: 2012-05-12
The attached file is working perfectly on my server.
What I need is to be able to attach more than one file - I need to be able to attach up to 4 files

Please can you help me with the additional code
send-email-form.php
0
Comment
Question by:doctorbill
  • 20
  • 14
  • 2
36 Comments
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 63 total points
ID: 36593877
I can show you how to upload multiple files.  Here is a teaching example that shows the essential moving parts.  Sorry, but I do not think we want to change your code.  Hopefully the example here will show you the right principles to follow as you change the way you use the $_FILES array to implement your own solution.
<?php // RAY_upload_example.php
error_reporting(E_ALL);


// MANUAL REFERENCE PAGES
// http://php.net/manual/en/features.file-upload.php
// http://php.net/manual/en/features.file-upload.common-pitfalls.php
// http://php.net/manual/en/function.move-uploaded-file.php


// PHP 5.1+  SEE http://php.net/manual/en/function.date-default-timezone-set.php
date_default_timezone_set('America/Chicago');

// ESTABLISH THE NAME OF THE 'uploads' DIRECTORY
$uploads = 'RAY_junk';

// ESTABLISH THE BIGGEST FILE SIZE WE CAN ACCEPT - ABOUT 8 MB
$max_file_size = '8192000';

// ESTABLISH THE MAXIMUM NUMBER OF FILES WE CAN UPLOAD
$nf = 3;

// ESTABLISH THE KINDS OF FILE EXTENSIONS WE CAN ACCEPT
$file_exts = array
( 'jpg'
, 'gif'
, 'png'
, 'txt'
, 'pdf'
)
;

// LIST OF THE ERRORS THAT MAY BE REPORTED IN $_FILES[]["error"] (THERE IS NO #5)
$errors = array
( 0 => "Success!"
, 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"
, 5 => "UNDEFINED ERROR"
, 6 => "Missing a temporary folder"
, 7 => "Cannot write file to disk"
)
;




// IF THERE IS NOTHING IN $_POST, PUT UP THE FORM FOR INPUT
if (empty($_POST))
{
    ?>
    <h2>Upload <?php echo $nf; ?> file(s)</h2>

    <!--
        SOME THINGS TO NOTE ABOUT THIS FORM...
        ENCTYPE IN THE HTML <FORM> STATEMENT
        MAX_FILE_SIZE MUST PRECEDE THE FILE INPUT FIELD
        INPUT NAME= IN TYPE=FILE DETERMINES THE NAME YOU FIND IN $_FILES ARRAY
        ABSENCE OF ACTION= ATTRIBUTE IN FORM TAG CAUSES POST TO SAME SCRIPT
    -->

    <form name="UploadForm" enctype="multipart/form-data" method="post">
    <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max_file_size; ?>" />
    <p>
    Find the file(s) you want to upload and click the "Upload" button below.
    </p>

    <?php // CREATE INPUT STATEMENTS FOR UP TO $n FILE NAMES
    for ($n = 0; $n < $nf; $n++)
    {
        echo "<input name=\"userfile$n\" type=\"file\" size=\"80\" /><br/>\n";
    }
    ?>

    <br/>Check this box <input autocomplete="off" type="checkbox" name="overwrite" /> to <strong>overwrite</strong> existing files.
    <input type="submit" value="Upload" />
    </form>
    <?php
    die();
}
// END OF THE FORM SCRIPT



// WE HAVE GOT SOMETHING IN $_POST - RUN THE ACTION SCRIPT
else
{
    // THERE IS POST DATA - PROCESS IT
    echo "<h2>Results: File Upload</h2>\n";

    // ACTIVATE THIS TO SEE WHAT IS COMING THROUGH
    //    echo "<pre>"; var_dump($_FILES); var_dump($_POST); echo "</pre>\n";

    // ITERATE OVER THE CONTENTS OF $_FILES
    foreach ($_FILES as $my_uploaded_file)
    {
        // SKIP OVER EMPTY SPOTS - NOTHING UPLOADED
        $error_code    = $my_uploaded_file["error"];
        if ($error_code == 4) continue;

        // SYNTHESIZE THE NEW FILE NAME
        $f_type    = trim(strtolower(end    (explode( '.', basename($my_uploaded_file['name'] )))));
        $f_name    = trim(strtolower(current(explode( '.', basename($my_uploaded_file['name'] )))));
        $my_new_file = getcwd() . '/' . $uploads . '/' . $f_name . '.' . $f_type;
        $my_file     =                  $uploads . '/' . $f_name . '.' . $f_type;

        // OPTIONAL TEST FOR ALLOWABLE EXTENSIONS
        if (!in_array($f_type, $file_exts)) die("Sorry, $f_type files not allowed");

        // IF THERE ARE ERRORS
        if ($error_code != 0)
        {
            $error_message = $errors[$error_code];
            die("Sorry, Upload Error Code: $error_code: $error_message");
        }

        // GET THE FILE SIZE
        $file_size = number_format($my_uploaded_file["size"]);

        // IF THE FILE IS NEW (DOES NOT EXIST)
        if (!file_exists($my_new_file))
        {
            // IF THE MOVE FUNCTION WORKED CORRECTLY
            if (move_uploaded_file($my_uploaded_file['tmp_name'], $my_new_file))
            {
                $upload_success = 1;
            }
            // IF THE MOVE FUNCTION FAILED
            else
            {
                $upload_success = -1;
            }
        }

        // IF THE FILE ALREADY EXISTS
        else
        {
            echo "<br/><b><i>$my_file</i></b> already exists.\n";

            // SHOULD WE OVERWRITE THE FILE? IF NOT
            if (empty($_POST["overwrite"]))
            {
                $upload_success = 0;
            }
            // IF WE SHOULD OVERWRITE THE FILE, TRY TO MAKE A BACKUP
            else
            {
                $now    = date('Y-m-d');
                $my_bak = $my_new_file . '.' . $now . '.bak';
                if (!copy($my_new_file, $my_bak))
                {
                    echo "<br/><strong>Attempted Backup Failed!</strong>\n";
                }
                if (move_uploaded_file($my_uploaded_file['tmp_name'], $my_new_file))
                {
                    $upload_success = 2;
                }
                else
                {
                    $upload_success = -1;
                }
            }
        }

        // REPORT OUR SUCCESS OR FAILURE
        if ($upload_success == 2) { echo "<br/>It has been overwritten.\n"; }
        if ($upload_success == 1) { echo "<br/><strong>$my_file</strong> has been saved.\n"; }
        if ($upload_success == 0) { echo "<br/><strong>It was NOT overwritten.</strong>\n"; }
        if ($upload_success < 0)  { echo "<br/><strong>ERROR: $my_file NOT SAVED - SEE WARNING FROM move_uploaded_file() COMMAND</strong>\n"; }
        if ($upload_success > 0)
        {
            echo "$file_size bytes uploaded.\n";
            if (!chmod ($my_new_file, 0755))
            {
                echo "<br/>chmod(0755) FAILED: fileperms() = ";
                echo substr(sprintf('%o', fileperms($my_new_file)), -4);
            }
            echo "<br/><a href=\"$my_file\">See the file $my_file</a>\n";
        }
    // END FOREACH ITERATOR - EACH ITERATION PROCESSES ONE FILE
    }
}

Open in new window

0
 

Author Comment

by:doctorbill
ID: 36594863
I would not know how to incorporate this into my code. Is it not possible for you to incorporate just what is needed to allow and array to work in my code - just to get me started
0
 

Author Comment

by:doctorbill
ID: 36594871
Also, the files need to be as attachments to an email
0
 

Author Comment

by:doctorbill
ID: 36594884
Sorry Ray - I should say that this is excellent code for file uploading - it will really help me for when I just need file uploads to a directory. I especially like the result page with file links
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36594981
For anything related to emails  (unless it's a very basic email) I tend to use phpMailer.

Once you've created an instance of phpMailer and done all the usual settings, to, from etc you attach a file like this:

$mail->AddAttachment('files/invoice-user-1234.pdf', 'invoice.pdf');

Open in new window


This would attach the file invoice-user-1234.pdf in the files folder to the email as a file called Invoice.pdf.

You can simply call AddAttachment() multiple times to add multiple files.

To get more information on phpMailer please see here:
http://sourceforge.net/projects/phpmailer/

I use it for pretty much everything to do with emails, including sending multiple attachments and it works fine.

This page has some more examples on:
http://phpmailer.worxware.com/index.php?pg=examples

Hope this helps

Cheers

Matt
0
 

Author Comment

by:doctorbill
ID: 36595150
I am using windows. I really don't understand how to use the phpMailer - the example I downloaded needs SPAW2 - what is this ?
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36595167
I'm not sure what spaw2 is, I believe phpMailer is a wrapper class around the standard mail() function but that makes it easier to work with.  So, in theory if you are able to use mail() you should be able to include the phpMailer class file and use it without too much trouble.

0
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 63 total points
ID: 36595197
I think this is not really a question - it is more of a requirement for application development and for that you might want to consider hiring a developer (if you do not have the time to do the work yourself -- time is money, after all).  We can show teaching examples and the like, but most of the time it is not possible for us to write applications.

Sidebar note: phpMailer is an excellent class.  It does not wrap or abstract the PHP mail() function.  The PHP mail() function makes a single connect-send-disconnect for each message.  phpMailer makes a single connect, then sends all the messages - much more efficient.
0
 

Author Comment

by:doctorbill
ID: 36595396
ok - I have got the phpmailer on my system. Could you please send me a complete basic working copy of a page form which is using phpmailer so I can see what it is supposed to look like
0
 

Author Comment

by:doctorbill
ID: 36713683
Thanks - I managed to get phpmailer working for me.

Question:
If I use the following it attaches a file with no problem:
1:
$mail->AddAttachment('files/invoice-user-1234.pdf', 'invoice.pdf');

I need to be able to select the file to attach using a file browse field and then allow phpmailer to send it
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36715080
hi doctorbill,

glad to hear you have managed to get phpMailer working.  To do what you are asking would require to combine some php script that handles multiple file uploads (such as that from Ray above) and then once the file uploads have been processed you simply call the $mail->AddAttachment() function to add the file.

So you process the file uploads in a loop, check that they are the correct file type and any other validation you need, once you are happy with them you ise $mail->AddAttachment() to add it to your email object, then send the email.

Sorry, but I haven't got the time to put together some example code at the moment but that's the general idea.

Cheers

Matt
0
 

Author Comment

by:doctorbill
ID: 36718640
does the processing take place in the user data entry form or the page used to send the data
0
 

Author Comment

by:doctorbill
ID: 36917957
Could someone please give me some code for the loop mentioned above - I am happy to adapt code but I need somewhere to start
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36938399
hi doctorbill,

I've put together a really quick example of handling multiple file uploads, sending email with HTML content and how to attach multiple files to an email.

Please note it's a quick example, there isn't a lot of error handling in it, and probably doesn't conform to many people's idea of best practice.  But, I've tested it and it works, so hopefully it should point you in the right direction.

<?php

include 'includes/phpMailer/class.phpmailer.php';

if (isset($_FILES['userfile']) && is_array($_FILES['userfile']) && count($_FILES['userfile'])) {
	
	// Uncomment the line below to see the contents of the $_FILES array 
	# echo '<pre>'; print_r($_FILES); echo '</pre>';	
	
	// Prepare $mail object, don't forget to change some of the options to suit your specific needs.
	$mail = new phpmailer();
	$mail->From = 'email@somewhere.com';
	$mail->FromName = 'Name of sender';
	$mail->AddAddress('forename.surname@email.com');
	$mail->Subject = 'Example HTML email with attachments';
	$mail->IsHTML(true);
	$mail->Body = '
	<html>
		<head>
		
		</head>
		<body>
			<p>Hi, hopefully there should be some files attached to this email.</p>
		</body>
	</html>
	';
	$mail->AltBody = "This is the content shown to users who can't accept HTML email";
	
	$tmp_folder = $_SERVER['DOCUMENT_ROOT'] . '/tmp/';
	
	for ($i = 0; $i < count($_FILES['userfile']['error']); $i++) {
		$name = $_FILES['userfile']['name'][$i];
		$error = $_FILES['userfile']['error'][$i];
		$type = $_FILES['userfile']['type'][$i];
		$tmp_name = $_FILES['userfile']['tmp_name'][$i];
		$size = $_FILES['userfile']['size'][$i];
		
		if ($error != 0) {
			// Something went wrong with this file upload.
			// Check here for error codes explained: http://www.php.net/manual/en/features.file-upload.errors.php
			// One example of what to do here would be to add a note to the email saying the file failed to upload etc...
		}
		else {
			// Everything was fine...	
			
			// Move the file from the email to a temporary location...
			// Note: basename() function takes a string path and returns only the training name part, e.g. the filename
			if (move_uploaded_file($tmp_name, $tmp_folder . basename($name))) {
				
				// We have moved the file successfully, so attach to the email...
				$mail->AddAttachment($tmp_folder . basename($name));
				
				// Note, we could have used the second parameter to AddAttachment to change the filename as it's attached, e.g.
				// $mail->AddAttachment($tmp_folder . basename($name), 'Some-other-filename.doc');
				// This can be useful if you store files on your server with random filenames, but want them attached as a specific name etc
				// or if the filename is invoice-user-1234.pdf on your server and you want to attach it as invoice.pdf etc
			}
			else {
				// Unable to move the file to a temporary location...	
				// Maybe add a note to the email saying extra files were uploaded but failed to be processed
			}
		}
	}
	
	// Hopefully at this point, we have accepted the files uploaded, moved them to a temporary 
	// location and have attached them to the email, next step is to send the email.
	
	if ($mail->Send()) {
		echo '<p>The email sent successfully.</p>';	
	}
	else {
		echo '<p>The email failed to send.</p>';	
	}
}

?>
<form enctype="multipart/form-data" action="test.php" method="POST">

    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />

    File 1: <input name="userfile[]" type="file" /><br />
    File 2: <input name="userfile[]" type="file" /><br />
    File 3: <input name="userfile[]" type="file" /><br />
    
    <input type="submit" value="Send File" />
</form>

Open in new window


I've put a few comments in there that may help explain the process and give you some more pointers.

I hope this helps.

Cheers,

Matt
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36938415
Hi,

Just for a bit more info, there is use of a $tmp_folder in the code above.  This is simply a folder called 'tmp' that I created within my document root to store the files in.  You will possibly need to allow write permissions on this folder however this depends on your hosts configuration.

Also, one thing I didn't add was anything to tidy up this tmp folder, it may be a good idea to delete the files once the email has been sent.  You can delete a file using unlink(), more info here http://www.php.net/manual/en/function.unlink.php
0
 

Author Comment

by:doctorbill
ID: 36941999
When I use the code I get a page not displayed error message
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36943619
Hi doctorbill,

My apologies, I had made a mistake in the original code, which one of the moderators kindly corrected for me however something has gone a bit wrong with the code showing up here, the &#9; should be a tab character.  I'm in conversation with one of the moderators and I believe they are going to try and sort it out, please check back again shortly to see if the code has been corrected and displaying correctly.

Thanks,

Matt
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36943828
Hi doctorbill,

Just a quick message to let you know JustAMod has sorted the problem with the code, please copy/paste again and give it a try.  Don't forget to change the appropriate $mail-> settings so they are correct for yourself, namely AddAddress() at the very least or you won't receive the email.

Let me know how you get on and if there's anything else I can help with.

Cheers.

P.S. Thanks again for JustAMod and all of the moderators on here, you guys are doing a brilliand job.  Cheers.

Matt
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:doctorbill
ID: 36944194
The page is now working - I will test it on my main server and let you know
0
 

Author Comment

by:doctorbill
ID: 36945704
I get the following when uploading some test images:

PHP Warning: move_uploaded_file(/tmp/Blue hills.jpg) [function.move-uploaded-file]: failed to open stream: No such file or directory in C:\Inetpub\wwwroot\PHPMailer_5.2.0\examples\attachments_test\test.php on line 48 PHP Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move 'C:\WINDOWS\Temp\phpA4B.tmp' to '/tmp/Blue hills.jpg' in C:\Inetpub\wwwroot\PHPMailer_5.2.0\examples\attachments_test\test.php on line 48
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36947081
You need to either create the tmp folder of change the code so that files are stored in a folder that already exists.
0
 

Author Comment

by:doctorbill
ID: 36947280
I have created the tmp folder and appropriate permissions but I am not sure where it's location should be
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36947484
line 29 of the code above is the following:

$tmp_folder = $_SERVER['DOCUMENT_ROOT'] . '/tmp/';

Open in new window


If you leave this setting as it is now then you will need to create the 'tmp' folder with correct permission in the document root of your site (typically this would be htdocs or public_html depending on your host).

Hope that helps.

Matt
0
 

Author Comment

by:doctorbill
ID: 36947525
I have created it in my IIS setup as follows:
c:\inetpub\wwwroot\tmp

full permissions
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36947541
Hi,

is it giving you an error or anything that may help diagnose the problem?

Thanks,

Matt
0
 

Author Comment

by:doctorbill
ID: 36947553
ok - I am now getting "email successfully sent" and I get an email but no attachments
0
 

Author Comment

by:doctorbill
ID: 36947570
no errors at all - just successfully sent
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36947584
In the code, there is an if statement for if(move_uploaded_file... check out the else { that follows this statement and add something in there, such as exit('If this sentence shows up then the move_uploaded_file failed');

E.g.

                        if (move_uploaded_file($tmp_name, $tmp_folder . basename($name))) {
                          // Don't change the code here... it's the bit below you need to add a die() message to
                        }
                        else {
                                // Unable to move the file to a temporary location...   
                                // Maybe add a note to the email saying extra files were uploaded but failed to be processed
                               die('If this sentence shows up then the move_uploaded_file() call failed');
                        }

Open in new window


Once you have done this, if the script dies with the message above then you know it's because the move_uploaded_file() function failed.  I would suggest you check the settings on your server relating to file uploads to make sure PHP is configured properly as the code works fine for me so could be a settings issue.

An example from this site: http://www.codingforums.com/archive/index.php/t-62919.html

Would suggest that when processing file uploads with folder locations on a windows server you need to use a different folder path with escaped backslashes.

move_uploaded_file($_FILES['form_image']['tmp_name'], "D:\\Inetpub\\fsstrath\\Live\\upl\\uploads\\".$_FILES['form_image']['name']);

Open in new window


The above is copy/paste from the example on that website, notice the folder location is explicitly defined and uses two backlashes.  This is as a single backslash has a special meaning in PHP.

Try the following:
$tmp_folder = "C:\\Inetpub\\wwwroot\\tmp\\";

Open in new window


Change the $tmp_folder line to the example here and give it another try?

Cheers
0
 

Author Comment

by:doctorbill
ID: 36947711
Still get the successfully sent message and the emails but no attachments
0
 

Author Comment

by:doctorbill
ID: 36947765
I have set my php.ini file to:

upload_tmp_dir = "c:\inetpub\wwwroot\tmp"  
still the same response
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36947839
the php setting is where the files are stored straight from the browser upload, you then need to use the move_uploaded_file() function to move them to your own location so you can work with the files.

What I would suggest is create yourself a simple php page that accepts a single file upload and see if that works.  Include using the move_uploaded_file() function to a new location to check thats working properly.

The script I created was on a linux server so there's a chance there could be an issue somewhere there, all I can say is that it worked fine for my on my hosting server.  It may need tweaking so that it works for you, especially if you are using windows.

As I said, try creating a simple upload script, that moves the file somewhere else, then check if the file has been moved and everything works.  If so then you know your php installation is configured to allow file uploads properly and you can try to adjust the script above accordingly.

Cheers

Matt
0
 

Author Comment

by:doctorbill
ID: 36947944
If I physically add three files to the c:\inetpub\wwwroot\tmp directory and then add the same file names to the browse boxes in the test.php form from my computer, I get an email with only one attachment - the attachment is the first file alphabetically
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36948115
Can you upload the file you are using in its entirity and I will install a webserver and php on my machine to try and figure it out.

It's likely to be a permissions issue or something like that maybe?
0
 
LVL 4

Assisted Solution

by:MattJellings
MattJellings earned 437 total points
ID: 36948126
Don't forger to change the email to a fake one before uploading or people with know your email address.

Also can I ask what operating system you are running this one and which webserver and version of php please.

Thanks
0
 

Author Comment

by:doctorbill
ID: 36950260
I am very grateful for your efforts on this

PHP version: 5.2.8


test.php
0
 

Author Closing Comment

by:doctorbill
ID: 37082439
good response
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now