Lesson 30 - Upload a file
Features
While we typically do not provide the ability to upload a document in a request info form, we usually do provide this feature in submit resume and trouble ticket forms.
So, what we want to allow the visitor to upload a dcoument.
The next lesson will show how to send the file as an email attachment.
|

Click here to see a larger image
|
Actions
 |
Click to see Lesson30_UploadFile.php in action on this tutorial site. Note: if you enter name an email in this form, you will send me an email. |
Download this file: Lesson30_UploadFile.txt to your PC. Change:
- the extension to php
- the recipient address
- the pointers to the style sheet
- the pointers to the directory where you want the text file
- the pointers to the directory where you will store the uploaded file
Then upload all to your website. The thank yous should be there from the previous lesson.
Make sure the file permissions on the directory/file to be written are correct. See Gotchas below.
Surf to the Lesson30_UploadFile.php file on your website with your browser. You should see results similar to the image above on the right.
After completing the form and clicking Send me more info:
Gotchas
File permissions! PHP must be able to write to your temporary storage directory ($tempDirectory).
Some restrictive firewalls may not let file uploads happen via a form with enctype="multipart/form-data".
Source Code
This example assumes that we have set the directory/file permissions outside of PHP to allow the PHP code to write to the file.
The <form> tag was changed to allow files to be uploaded. A new <input type="file"> was added.
PHP populates the $_FILES superglobal array with information on the uploaded file. We test on this array to check if the file was uploaded to the PHP temp upload area. Then we change the filename to prevent duplicate filenames. We take a filename of the form "first second third.doc" and change it to "first_second_third_yyyymmdd_xxx.doc", where xxx equals the first 3 letters of the person's last name. For example: John Smiths "resume for job.doc" becomes "resume_for_job_20030818_smi.doc". Finally, we move the uploaded file (using move_uploaded_file) to our temporary storage area with its new name.
| |
<?php
ob_start(); /* Start buffer so we can use header anywhere in the page */
$fileToBeWritten = "../../../Data_Repository/Acme_Demographic_Data.txt";
$recipientAcme = "dave@marketingtactics.com";
$senderAcme = "dave@barnesfamily.com";
$tempDirectory = "../../../temporary_storage/"; /* This is OUR temporary storage area, not the PHP temp area for uploads */
?>
<html>
<head>
<title>A Request Info Form uploads a file.</title>
<link rel="stylesheet" href="/PHP_Tutorials/Styles/PHP_Tutorials_Forms_Style.css" type="text/css">
</head>
<body>
<h1>Request Information from the Acme Company</h1>
<form method="POST" enctype="multipart/form-data" name="FirstEmailForm" action="<?php echo($PHP_SELF); ?>" >
<table width="550" border="0" cellspacing="2" cellpadding="0" bgcolor="#DFDFDF">
<tr>
<td colspan="2" class="FormCategoryName">About You</td>
</tr>
<tr>
<td width="200" class="FormVariableName" align="right">
First Name:<span style="color:red">*</span>
</td>
<td width="344">
<input type="text" name="contactFirstName" value="<?php print $_POST['contactFirstName']; ?>" >
<span class="Footer" style="color:red">* = Required</span>
</td>
</tr>
<tr>
<td width="200" class="FormVariableName" align="right">
Last Name:<span style="color:red">*</span>
</td>
<td width="344">
<input type="text" name="contactLastName" value="<?php print $_POST['contactLastName']; ?>" >
</td>
</tr>
<tr>
<td width="200" class="FormVariableName" align="right">
Email:<span style="color:red">*</span>
</td>
<td width="344">
<input type="text" name="contactEmail" value="<?php echo $_POST['contactEmail']; ?>" >
</td>
</tr>
<tr>
<td valign="Top" class="FormCategoryName" colspan="2">Interests</td>
</tr>
<td align="right" valign="Top" class="FormVariableName">Favorite Characters:</td>
<td valign="Top">
<?php
if($_POST['contactCharacterBugs'] == "YES")
{ $cbvalue = "checked"; }
else
{ $cbvalue = "unchecked"; }
echo("<input type='checkbox' name='contactCharacterBugs' value='YES'" .$cbvalue .">Bugs Bunny<br>");
if($_POST['contactDaffy'] == "YES")
{ $cbvalue = "checked"; }
else
{ $cbvalue = "unchecked"; }
echo("<input type='checkbox' name='contactDaffy' value='YES'" .$cbvalue .">Daffy Duck<br>");
if($_POST['contactRoadRunner'] == "YES")
{ $cbvalue = "checked"; }
else
{ $cbvalue = "unchecked"; }
echo("<input type='checkbox' name='contactRoadRunner' value='YES'" .$cbvalue .">Road Runner<br>");
if($_POST['contactCoyote'] == "YES")
{ $cbvalue = "checked"; }
else
{ $cbvalue = "unchecked"; }
echo("<input type='checkbox' name='contactCoyote' value='YES'" .$cbvalue .">Wiley Coyote");
?>
</td>
</tr>
<tr>
<td align="right" valign="Top" class="FormVariableName" width="200"> Age Group:</td>
<td valign="Top" width="344">
<select name="contactAgeGroup">
<option value="NONE">Select One</option>
<option value="Kid">Child</option>
<option value="Teen">Teenager</option>
<option value="TatooFreak">GenX</option>
<option value="Adult">Adult</option>
<option value="OldFart">Senior</option>
<?php
switch ($_POST['contactAgeGroup'])
{
case "Kid":
print ("<option value=\"Kid\" selected>Child<option>");
break;
case "Teen":
print ("<option value=\"Teen\" selected>Teenager<option>");
break;
case "TatooFreak":
print ("<option value=\"TatooFreak\" selected>GenX<option>");
break;
case "Adult":
print ("<option value=\"Adult\" selected>Adult<option>");
break;
case "OldFart":
print ("<option value=\"OldFart\" selected>Senior<option>");
break;
}
?>
</select>
</td>
</tr>
<tr>
<td align="right" valign="Top" class="FormVariableName" width="200">Please add to me to your mailing list:</td>
<td valign="Top" width="344">
<?php
if ($_POST['contactAddMailingList'] == "YES")
{
echo ("<input type='radio' name='contactAddMailingList' value='YES' checked>YES<br>
<input type='radio' name='contactAddMailingList' value='No'>No");
}
elseif ($_POST['contactAddMailingList'] == "No")
{
echo ("<input type='radio' name='contactAddMailingList' value='YES'>YES<br>
<input type='radio' name='contactAddMailingList' value='No' checked>No");
}
else
{
echo ("<input type='radio' name='contactAddMailingList' value='YES'>YES<br>
<input type='radio' name='contactAddMailingList' value='No'>No");
}
?>
</td>
</tr>
<tr>
<td align="right" valign="Top" class="FormVariableName" width="200">My attached file:</td>
<td valign="Top" width="344">
<input type="hidden" name="MAX_FILE_SIZE" value="500000">
<!-- some systems require that MAX_FILE_SIZE be set to a certain number of bytes-->
<input type="file" name="contactUploadedFile">
</td>
</tr>
<tr>
<td align="right" valign="Top" class="FormVariableName" width="200">Comments:</td>
<td valign="Top" width="344">
<textarea name="contactComments" rows="4" cols="40"><?php print $_POST['contactComments']; ?></textarea>
</td>
</tr>
<tr>
<td width="200" class="FormVariableName" align="right">
</td>
<td width="344">
<input type="hidden" name="firstPass" value="No">
<input type="submit" name="subRequestButton" value="Send me more info">
<br>
<span class="Footer">Please click only once.</span>
</td>
</tr>
</table>
</form>
<?php
if($_POST['firstPass'] == "No")
{
/* Set variables equal to their "posted" values". We need to do this because "register_globals = off" is the default. */
$contactFirstName = $_POST['contactFirstName'];
$contactLastName = $_POST['contactLastName'];
$contactCharacterBugs = $_POST['contactCharacterBugs'];
$contactDaffy = $_POST['contactDaffy'];
$contactRoadRunner = $_POST['contactRoadRunner'];
$contactCoyote = $_POST['contactCoyote'];
$contactEmail = $_POST['contactEmail'];
$contactAgeGroup = $_POST['contactAgeGroup'];
$contactAddMailingList = $_POST['contactAddMailingList'];
$contactComments = $_POST['contactComments'];
/* If the user skipped required fields or entered invalid values, write an appropriate error message. */
if ($contactFirstName == "")
exit("<p class='PhpError'>Your First Name is missing.</p>");
if ($contactLastName == "")
{
exit("<p class='PhpError'>Your Last Name is missing.</p>");
}
if (!(eregi("^[a-z0-9\._-]+@+[a-z0-9\._-]+\.+[a-z]{2,4}$",$contactEmail))):
exit("<p class='PhpError'>Email Address appears to be invalid.</p>");
endif;
$emailDomain = ltrim(strstr($contactEmail, '@'), '@');
if(!(checkdnsrr($emailDomain, ANY)))
exit("<p class='PhpError'>Email Address Domain can not be found on the internet.</p>");
/* Ensure that the file was uploaded, renamed and moved to your personal temporary storage area. */
/* We rename the uploaded file from filename.ext (the file is assumed
to have an extension) to filename_yyyymmdd_xxx.ext, where xxx equals
the first 3 letters of the person's last name. */
/* The whole intent of renaming is to prevent us from receiving the
same filenames as attachments. Think about the submit resume case. */
/* Would you rather receive: resume_20030818_jon.doc and
resume_20030819_smi.doc or would you prefer: resume.doc and resume1.doc.
Or worse, the second resume.doc overwrites the first resume.doc */
/* This method assumes low traffic volume. For higher volumes,
you could add minutes or a random number to the date. */
if(!isset($_FILES['contactUploadedFile']))
exit("<p class='PhpError'>The expected file wasn't a part of the submitted form.</p>");
if($_FILES['contactUploadedFile']['error'] != UPLOAD_ERR_OK)
exit("<p class='PhpError'>The file uploaded failed.</p>");
$dateForUploadedFile = date("Ymd");
$firstThreeLettersLastName = substr($contactLastName, 0, 3);
$charactersToBeAdded = "_" .$dateForUploadedFile ."_" .$firstThreeLettersLastName;
$uploadedFileName = str_replace(" ", "_", $_FILES['contactUploadedFile']['name']);
/* All spaces in filename replaced with underscores */
$positionOfLastPeriodInUploadFileName = strrpos($uploadedFileName, ".");
$newUploadedFileName = substr_replace($uploadedFileName,
$charactersToBeAdded, $positionOfLastPeriodInUploadFileName, 0);
if(!move_uploaded_file($_FILES['contactUploadedFile']['tmp_name'],
$tempDirectory . $newUploadedFileName))
exit("<p class='PhpError'>Moving the uploaded file failed.</p>");
/* Construct list of favorite characters */
$favoriteCharactersList = "";
if ($contactCharacterBugs == "YES")
$favoriteCharactersList .= "Bugs Bunny, ";
if($contactDaffy == "YES")
$favoriteCharactersList .= "Daffy Duck, ";
if($contactRoadRunner == "YES")
$favoriteCharactersList .= "Road Runner, ";
if($contactCoyote == "YES")
$favoriteCharactersList .= "Wiley Coyote";
/* Create Date Time in Human Readable Form */
$humanDateTime = date("Y") . strtoupper(date("M")) . date("d H:i");
/* Replace all LineFeeds within Comments with 2 spaces. */
$commentsSingleLine = str_replace("\n", " ", $contactComments);
$commentsSingleLine = str_replace("\r", " ", $commentsSingleLine);
/* Construct the email messages */
$messageToAcme = "Please send me more information about Acme products";
$messageToAcme .= "\n\n First Name = " . $contactFirstName;
$messageToAcme .= "\n Last Name = " . $contactLastName;
$messageToAcme .= "\n Email = " . $contactEmail;
$messageToAcme .= "\n\n My interests are:";
$messageToAcme .= "\n Favorite Characters = " . $favoriteCharactersList;
$messageToAcme .= "\n Age Group = " . $contactAgeGroup;
$messageToAcme .= "\n Add me to mailing list = " . $contactAddMailingList;
$messageToAcme .= "\n\n Comments = " . $contactComments;
$fullAcmeName = $contactFirstName ." " .$contactLastName;
$mailAcmeHeaders = "From: \"".$fullAcmeName."\"<".$contactEmail.">\n";
$mailAcmeHeaders .= "Reply-to: ".$contactEmail;
$messageToRequestor = "Thanks, " .$contactFirstName .", for requesting information about Acme products";
$messageToRequestor .= "\n Your email will totally ignored just like 38% of the F500 ignore emails.";
$mailRequestorHeaders = "From: \"Acme Wizard\"<". $senderAcme .">\n";
$mailRequestorHeaders .= "Reply-to: " .$senderAcme;
/* Build the line of data to be appended to the data file */
/* WARNING - Do not change the order of the items in the file */
/* This file is imported (using a map) by Marketing */
$messageDataLine = $humanDateTime . "|";
$messageDataLine .= "reqinfo" . "|";
$messageDataLine .= $contactFirstName . "|";
$messageDataLine .= $contactLastName . "|";
$messageDataLine .= $contactEmail . "|";
$messageDataLine .= $favoriteCharactersList . "|";
$messageDataLine .= $contactAgeGroup . "|";
$messageDataLine .= $contactAddMailingList . "|";
$messageDataLine .= $commentsSingleLine . "|" . "\n";
if (mail($recipientAcme, "Please Send Acme Info", $messageToAcme, $mailAcmeHeaders))
{
mail ($contactEmail, "Acme Request Received", $messageToRequestor, $mailRequestorHeaders);
$handleAcmeFile = fopen($fileToBeWritten, "a");
$fwriteSuccess = fwrite($handleAcmeFile, $messageDataLine);
$fcloseSuccess = fclose($handleAcmeFile);
header("Location: ../../ThankYous/Thanks_Request_Info_Success.html"); /* Redirect browser */
exit; /* Make sure that code below does not get executed when we redirect. */
}
else
{
header("Location: ../../ThankYous/Thanks_Request_Info_Failure.html");
mail("webmaster@marketingtactics.com", "Acme, Request Info Failure", $messageToAcme, $mailAcmeHeaders);
exit;
}
}
?>
</body>
</html>
<?php
ob_end_flush();
?>
|
Final Thoughts
Now that we have uploaded a file, the next lesson will show how to attach that file to our email.
Addendum
When PHP receives our example form above, it will create $_FILES['myfile'], which actually represents a sub-array populated with information about the file that was uploaded. This information is:
name |
The name of the file as it was saved on the
client machine |
type |
The MIME type for the file |
size |
The size of the uploaded file (in
bytes) |
tmp_name |
The temporary name given to the file by
PHP |
error |
An integer error code (if something went
wrong) |
Source: Working with Forms in PHP, Part 2, by John Coggeshall, 05/01/2003
|