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.

 

Request Info Pretty
Click here to see a larger image

Actions

Arrow Red Right 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”:

  • you should receive the usual email with this in the body:
  • Please send me more information about Acme products

    Comments

  • your visitor should receive a confirming email
  • a line of text was written to the file
  • a file was uploaded to your temporary storage area
  • you should be sent to the Thank You page

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 Smith’s "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']; ?>" >
        &nbsp;<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($emailDomainANY)))
    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($contactLastName03);
  
$charactersToBeAdded "_" .$dateForUploadedFile ."_" .$firstThreeLettersLastName;
  
$uploadedFileName str_replace(" ""_"$_FILES['contactUploadedFile']['name']);
     
/* All spaces in filename replaced with underscores  */
  
$positionOfLastPeriodInUploadFileName strrpos($uploadedFileName".");
  
$newUploadedFileName substr_replace($uploadedFileName
$charactersToBeAdded
$positionOfLastPeriodInUploadFileName0);
  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

Go To MarketingTactics home