Hassan
Hassan

Reputation: 53

how to loop through FormData using php

Here I am Creating a FormData using ajax so I can Send some input files to php script then I can Save it as a blob in my database. The question is how can I dynamically loop through the FormData after sending it to php script so I can get each name dynamically and save what the user have uploaded and leave the empty inputs as it is

for more explanation:

<input id = "Pay_cert1"  type="file" name="" /> 
<input id = "Pay_cert2"  type="file" name="" /> 
<input id = "Pay_cert3"  type="file" name="" /> 
<input id = "Pay_cert4"  type="file" name="" /> 

then I get the values of inputs "if there is a value" and append it to my dataform

  var Pay_cert1= $('#Pay_cert1').prop('files')[0];   
    var Pay_cert2= $('#Pay_cert2').prop('files')[0];   
    var Pay_cert3= $('#Pay_cert3').prop('files')[0];   
    var Pay_cert4= $('#Pay_cert4').prop('files')[0];   


var form_data = new FormData();                  
if(document.getElementById("Pay_cert1").files.length != 0)
{
form_data.append('Pay_cert1', Pay_cert1); 
}
if(document.getElementById("Pay_cert2").files.length != 0)
{
form_data.append('Pay_cert2', Pay_cert2);
}
if(document.getElementById("Pay_cert3").files.length != 0)
{
form_data.append('Pay_cert3', Pay_cert3);
}
if(document.getElementById("Pay_cert4").files.length != 0)
{
form_data.append('Pay_cert4', Pay_cert4);
}


 $.ajax({
        url: 'Upload.php',
        cache: false,
        contentType: false,
        processData: false,
        data:form_data ,                         
        type: 'post',
       success : function(data) {
   }
     });

here in PHP I want to loop dynamically on my DataForm and get the tmpname of each file that have been appended only, So how can I say

foreach(name in $_FILES['']) // how can I loop here on DataForm and get each tmpname??
{
console.log( $_FILES['name']['tmp_name']); 
}

Upvotes: 0

Views: 702

Answers (2)

Professor Abronsius
Professor Abronsius

Reputation: 33804

If you were to use querySelectorAll to find all the file input elements you can iterate through them and assign name and value to the FormData object in a much cleaner way than shown above.

Each file can be appended to the variable which needs to use the array syntax for naming - ie: files[]

With that variable set the Ajax request ( here using fetch for simplicity ) the PHP code that processes the upload can then iterate through the $_FILES collection using files as the name - ie: $_FILES['files'] or whatever variable you assigned in fd.append('NAME[]',value) earlier.

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_FILES['files'] ) ){
        
        $output=array();
        
        foreach( $_FILES['files']['name'] as $i => $name ) {
        
            if( !empty( $_FILES['files']['tmp_name'][$i] ) ) {
                $name = $_FILES['files']['name'][$i];
                $size = $_FILES['files']['size'][$i];
                $type = $_FILES['files']['type'][$i];
                $tmp  = $_FILES['files']['tmp_name'][$i];
                $error= $_FILES['files']['error'][$i];
                $ext  = pathinfo( $name, PATHINFO_EXTENSION );
                
                # do what you need to save the files and generate some output to send back to the AJAX callback
                $output[]=array(
                    'name'=>$name,
                    'size'=>$size,
                    'type'=>$type,
                    'ext'=>$ext,
                    'date'=>date(DATE_ATOM)
                );
            }
        }
        
        exit( json_encode($output) );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title></title>
        <style>input{clear:both;display:block;margin:0.5rem 0;padding:0.5rem;}</style>
    </head>
    <body>
    
        <input type="file" name="Pay_cert1" />
        <input type="file" name="Pay_cert2" />
        <input type="file" name="Pay_cert3" />
        <input type="file" name="Pay_cert4" />
        <input type='button' value='Upload' />
        
        <script>
            document.querySelector('input[type="button"]').addEventListener('click',(e)=>{

              let url=location.href;    //'Upload.php';
              let fd = new FormData();

              document.querySelectorAll('input[type="file"][name^="Pay_cert"]').forEach(n => {
                  if ( n.files.length > 0 ) {
                      fd.append( 'files[]', n.files[0], n.name );
                  }
              });
              
              
              fetch( url, { method:'post', body:fd } )
                .then( r=>r.json() )
                .then( json=>{
                  console.log(json)
                })

            });
        </script>
    </body>
</html>

Upvotes: 1

Debuqer
Debuqer

Reputation: 385

Foreach looks like this in php

PHP: foreach

And this is how $_FILES looks

PHP: $_FILES

So in Upload.php you may change your code from

foreach(name in $_FILES['']) // how can I loop here on DataForm and get each tmpname??
{
console.log( $_FILES['name']['tmp_name']); 
}

to

foreach($_FILES as $key => $file ) { // $key is index and $file is item
     echo "this is ".$file['tmp_name'];  // like console.log in js
}

Now you can interate on $_FILES variable, It means will access on each temp_name

Upvotes: 1

Related Questions