Php - multi file upload - change status of the file basis hidden element

I am trying to upload multiple files using PHP which is working fine. Now in my form, I am displaying the file options dynamically along with the type of document it is, resume, id proof, etc.,

It is not necessary that the user should upload all the files at once, he can select whatever docs he has and use the submit button to upload them, after which I’d like to update that doc status to “Received”. While trying to do this, I am seeing that only last record is getting updated no matter how many files are selected.

Here’s my Form code -

<table class="table striped bordered border hoverable white">
  <?php
    $returnMsg = "";
    $docsNStatus="SELECT * FROM applicantdocs where username = '$login_session' and docStatus='Not Received'";
    if(!$result=mysqli_query($db,$docsNStatus))
      die('There was an error retrieving the information');

    echo "<form method='POST' action='../../actionHandler.php' enctype='multipart/form-data' target='resultFrame'>";

    while ( $row = $result->fetch_assoc() ){
      $uploadFileName = "fileUpload".$row['sno'];
      $docID = $row['sno'];
      echo "<tr>
        <td>".$row['docName']."</td>
        <td>".$row['docStatus']."</td>
        <td>
        <input type='hidden' name='docNumber' value='$docID'/>
        <input type='hidden' name ='docNumber_$docID' value='$docID'/> //Here I am dynamically setting the hidden element docnumber and the id 
        <label style= 'padding: 5px!important;' class='myLabel'>
            <input type='file' name='uploadingFiles[]' id='uploadBtn'/>
            <span>Upload doc</span>
        </label>
        
        </td></tr>";
    }
        
    echo "</table><br/><input type='submit' name ='uploadFile' value='Click here to upload files' class='formButton'/> ";
  ?>

PHP code:

if(isset($_POST["uploadFile"])){     

	$userIDquery = "SELECT firstName, lastName from applicants WHERE username= \"{$login_session}\"";
	$userRes= mysqli_query($db, $userIDquery);
	$userRec= mysqli_fetch_array($userRes, MYSQLI_ASSOC);
	$lName = $userRec["firstName"].'_'.$userRec["lastName"];

	$storageLocation = "Assets/Documents/".$lName."/";

    $errors = array();
    $extension = array('jpg','png','jpeg','gif','pdf'); 
     
    $bytes = 1024;
    $allowedMB = 10;
    $totalBytes = $allowedMB * $bytes * 1024;
     
    foreach($_FILES["uploadingFiles"]["tmp_name"] as $key=>$tmp_name) {

		$docNo = mysqli_real_escape_string($db, $_POST["docNumber"]);
		$onlyDocNumToUpdate = mysqli_real_escape_string($db, $_POST["docNumber_".$docNo]);

        $uploadThisFile = true;
		
        $file_name=$_FILES["uploadingFiles"]["name"][$key];
        $file_tmp=$_FILES["uploadingFiles"]["tmp_name"][$key];
         
        $ext=pathinfo($file_name,PATHINFO_EXTENSION);

        if(!in_array(strtolower($ext),$extension)) {
            array_push($errors, "File type is invalid. Name:- ".$file_name);
            $uploadThisFile = false;
        }
         
        if($_FILES["uploadingFiles"]["size"][$key] > $totalBytes) {
            array_push($errors, "File size must be less than 10MB. Name:- ".$file_name);
            $uploadThisFile = false;
        }
         
        if($uploadThisFile){
            $filename=basename($file_name,$ext);
            $newFileName=$filename.$ext;                
            if(move_uploaded_file($_FILES["uploadingFiles"]["tmp_name"][$key], $storageLocation.$newFileName)){
				$query = "UPDATE applicantdocs set docStatus ='Received' 
				where username = '$login_session' 
				and sno=$onlyDocNumToUpdate";

				if(!mysqli_query($db, $query)){
					print '<br><b style="color:#B60000">Exception:</b> ';
					throw new Exception(showerror($db));
				} else
					print "The selected files have been uploaded successfully.";	
			}
        }
    }
     
    mysqli_close($db);
    $count = count($errors);
    if($count != 0){
        foreach($errors as $error){
            echo $error."<br/>";
        }
    }       
}

My form looks something like below -
enter image description here

Appreciate taking a look at it.

This simplest way of doing this is to have a document type table, with id (auto-increment integer) and name columns. You would then use the document type id in the applicantdocs table and use it as the index value in the name=‘uploadingFiles[…]’ attribute. To display the document type name(s), you would either just query the document type table or JOIN this table in a query with other tables holding the document type id.

When you loop over the array of submitted $_FILES data, the $key value will be the document type id. Everything else you currently have in the code with the hidden fields is not needed and will go away.

Speaking of a document type id, you should also have a user id (an auto-increment integer) column defined in the applicants table. You would store the user id in the applicantdocs table, as the login session value, and as the part of the assets/documents/ … path, instead of the username or concatenated name. By using the username/concatenated name in these place, creates a problem if you need to edit a username/name, could allow file path transversal, increases the data storage requirements, and results in slower queries.

BTW - you need add two different types of upload file error checking to your code -

  1. If the total size of the submitted form data exceeds the post_max_size setting, which is easy to do when uploading multiple files, both the $_POST and $_FILES arrays will be empty. Your current form processing code won’t do anything since $_POST[‘uploadFile’] won’t exist. You need to instead test if $_SERVER[‘REQUEST_METHOD’] == ‘POST’, then detect if the $_FILES array is empty to detect for this particular error.

  2. As you are looping over the $_FILES array, you need to test the [‘error’] element and only use the uploaded file information if there was no upload error and setup error messages and display them back to the user for errors that the user has control over and can correct.

Also, you should only store data that exists, so you should be INSERTing row(s) in the applicantdocs table when files are successfully upload (you would only UPDATE rows in the applicantdocs table if you are editing/correcting information.)

Sponsor our Newsletter | Privacy Policy | Terms of Service