Help needed with this file upload code

The following code from a page called “psf-create.php” works:

<!-- HTML5 Input Form  -->
<form action="../inc/psf-upload.php" method="post" enctype="multipart/form-data" class="pnc-label">
  Click "Browse" to select one image to upload:<br>then click "Upload Image" button...<br>
<input type="file" name="fileToUpload" id="fileToUpload">
<br>
<input type="submit" value="Upload Image" name="submit">
</form>

The above code accesses …/inc/psf-upload.php which is the following:

    <?php
    $target_dir = "../test-a/upload_folder/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $uploadOk = 1;
    $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

    // Check if image file is a actual image or fake image
    if(isset($_POST["submit"])) {
      $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
      if($check !== false) {
      //  echo "File is an image - " . $check["mime"] . ".";
        $uploadOk = 1;
      } else {
        echo "File is not an image.";
        $uploadOk = 0;
      }
    }

    // Check if file already exists
    //if (file_exists($target_file)) {
    //  echo "Sorry, file already exists.";
    //  $uploadOk = 0;
    //}

    // Check file size
    if ($_FILES["fileToUpload"]["size"] > 500000000) {
      echo "Sorry, your file is too large.";
      $uploadOk = 0;
    }

    // Allow certain file formats
    if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
    && $imageFileType != "gif" ) {
      echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
      $uploadOk = 0;
    }

    // Check if $uploadOk is set to 0 by an error
    if ($uploadOk == 0) {
      echo "Sorry, your file was not uploaded.";
    // if everything is ok, try to upload file
    } else {
      if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "<br>The file ". htmlspecialchars( basename( $_FILES["fileToUpload"]["name"])). " has been uploaded.";
      } else {
        echo "Sorry, there was an error uploading your file.";
      }
    }
    ?>

My problem is, upon successful upload it leaves the user on the page ‘psf-upload.php’ with a message such as:
The file babe-2972221.jpg has been uploaded.

Can somebody please help me achieve:
– (1) the user remains on page ‘psf-create.php’ (with all existing form-field data intact) with the ‘successful upload’ message in class=“warning-blue” inserted into that page, underneath the “Upload image” button.
– (2) on any of the 4 possible error conditions, the warning message such as “Sorry, there was an error uploading your file.” or any of the other 3 warnings are inserted into page ‘psf-create.php’ with class=“warning-red”, above the “Upload image” button…

Just put the form processing code and the form on the same page. To get the form to submit to the same page it is on, simply leave the entire action=’…’ attribute out of the form tag. The form processing code would be located above the start of the html document.

You are only showing us one form field for the file selection. This type of form field is read-only and cannot be set by any code as this would allow a web site to automatically grab any file it wants from the user’s computer. This field can only be set by the browser’s file selection dialog box through user action. If you have other types of fields in the form, you can set their value or selected/checked state, using php code, when you output the form.

To display a success message, you would store it in a session variable at the appropriate location in the form processing code. The form processing code should then execute a header() redirect to the exact same url of the current page upon success, to cause a get request for the page. You would have php code at the appropriate location in the html document to test, output, and delete the session variable. You can produce any specific markup you want in the php code that’s outputting the content.

You need to store the error messages in an array, using the form field name as the array index. This array is also an error flag, replacing the separate $uploadOk variable in your current code. If the array is empty, there are no errors. If the array is not empty, there are errors. You would test and output the content of this array at the appropriate location in the html document when you output the form.

Your existing form processing code has some issues and can be simplified -

  1. You should detect if a post method form has been submitted before referencing any of the form data.
  2. You should not attempt to detect if the submit button is set. It won’t be for some browsers/browser-versions and it won’t be if you ever switch to use ajax to submit the form data. If you have a case where there is more than one form to be processed on one page, store a value in a hidden field that uniquely identifies the form, then test that value to control which form processing code to execute.
  3. All the form processing code should be within the conditional logic that has tested if the form has been submitted. You currently have some code before/after that test.
  4. If the total size of the form data exceeds the post_max_size setting on the server, both the $_POST and $_FILES arrays will be empty. You must detect this condition in the form processing code and setup a message for the user telling them that the form data was too large and could not be processed (you would also log this information so that you know it is occurring and can for example increase the post_max_size value if appropriate.)
  5. After you have determined that there is data in the $_FILES array, you must test the [‘error’] element to find out if the file was successfully uploaded or not (there is a list of the error values and meanings the php.net document.) For the errors that the user has control over, you would setup a descriptive message telling the user what was wrong with the form submission. For the errors that the user cannot do anything about, you would setup a general failure message, then log all the information about the problem so that you will know what is occurring and can fix it.
  6. After you have determined that a file was successfully uploaded, you can begin to validate the file information.
  7. In the file extension check code, use an array for the list of allowed values, then use !in_array() (not in_array), rather than writing out conditional tests for each value.
1 Like

Your comments are very interesting and informative, but beyond my level of knowledge.
Would you be willing to do a re-write of my code to fix it?
And if Yes, how much would that cost me?

You could attempt to do each item, one at a time, thereby learning something in the process.

For the four main items -

  1. Requires rearranging the code and removing the action attribute from the form.
  2. If the type = ‘file’ field is the only form field at this time, nothing can be changed.
  3. Requires adding a session_start() statement, storing the success message in a session variable, rather than echoing it, performing a header() redirect, and adding code in the html document to test (isset), echo, and clear (unset) the session variable.
  4. Requires storing each error message in an array, rather than echoing it, and adding code in the html document to test (! (not) empty), loop over (foreach), and echo the contents of the array variable.

For the list of items -

  1. Requires changing the existing conditional test to use if($_SERVER['REQUEST_METHOD'] == 'POST')
  2. This item is related to item #1 and goes away when you do item #1 if there is only a single form and form processing code on the page.
  3. Requires rearranging the form processing code so that is all within a conditional statement.
  4. Requires adding a conditional test, an error message, and logging logic.
  5. Requires adding one or more conditional tests (a switch statement should be used), depending on how through you want to be, and logging logic.
  6. This is using your existing logic to validate the file information. Note: you should not use getimagesize() to test for valid images, use php’s Fileinfo extension instead, and the 500,000,000 maximum file size check value is pointless, because the default post_max_size and upload_max_filesize settings are smaller than this and won’t allow a file of that size to be uploaded (see items #4 and #5 on this list.)
  7. Requires defining an array with the permitted values in it and learning how to use in_array() to test if a value is in the array of the permitted values.

So I guess that means your not available for me to hire?
Thanks anyway.

Sponsor our Newsletter | Privacy Policy | Terms of Service