3

I m working on an html page that contains a form allowing users to enter their informations and upload files. all informations will be inserted in Mysql database.

in Javascript, im using XMLHttpRequest to send the files to the server and "upload.php" to rename (to avoid dupplicated names) and move them in the upload directory.
For better user experience, this will be done before submitting the whole form.

My question is : How can i store the new filenames (defined in upload.php)to use them in the form submission "submit.php"?
the reason for this is that in "submit.php", i insert first the user informations in "user" table and then select the "user_id" (auto increment) that will be inserted with filenames in the "files" table.

Could php sessions be an approach to do this ? is there another way? Thanks for your help

html:

<form action="submit.php" method="post" id="submitform">
<div>
<--!user info part1-->
</div>
<div id="filesContainer" class="eltContainer">
    <input type="file" id="filesList" multiple>
</div>
<div>
<--!user info part2-->
</div>

javascript:

var fd = new FormData()
var xhr = new XMLHttpRequest()
for (var i=0,nb = fichiers.length; i<nb; i++) {
    var fichier = fichiers[i]
    fd.append(fichier.name,fichier)
}
xhr.open('POST', 'upload.php', true)

upload.php :

<?php 
foreach($_FILES as $file){
    $filename = date('Y') . date('m') . date('d') . date('H') . date('i') . basename($_FILES[$file]['name']);
    move_uploaded_file( $file['tmp_name'],"../upload_dir/" .$filename);  
    }
exit;
6
  • 4
    simple: start a db transaction, insert a skeleton record (bare minimum necessary to create the record), get its insert ID, use that ID to build your filename, then update the record/commit the transaction once you've completed the file manipulations. Commented Oct 4, 2016 at 17:20
  • when inserting filename in the DB, i dont need the file insert id, but the user insert id(as foreign key). The problem is when i do file manipulation/insertion i havn't reached yet the user insertion wich comes after submitting the whole form.. i also want to minimize the db transactions. Thanks anyway Commented Oct 4, 2016 at 20:48
  • same thing holds. create a placeholder user record so you can get a userID, which you can then attach to the placeholder file record, blah blah blah. all you'd need afterwards is a janitor script to kill any abandoned skeletons so you don't fill the db with partials. Commented Oct 4, 2016 at 21:16
  • in this case, i'll need the file name or ID to attach the userID to the placeholder. The question remains, how can i store the file infos up to this point? Commented Oct 4, 2016 at 21:34
  • 1
    @BenS. Beware, your code allows users to upload files with somewhat arbitrary names. If I want to upload something-evil.exe, I can, and you'll just prepend the date on it. This isn't good. Furthermore, it's possible to move up in the file system by sending in ../ in the filename. This is very dangerous. Use UUID to generate a filename, or name files based on their IDs in your database. Commented Oct 5, 2016 at 2:30

1 Answer 1

1

I would consider using something like md5 for unique filenames.

Nevertheless you can push filenames into some array, and than return those filenames, as a result of post request, and put them back into some input field.

To retrieve the response simply add this lines to your code below open

xhr.onreadystatechange = function {
// If the request completed and status is OK
  if (req.readyState == 4 && req.status == 200) {
    // keep in mind that fileNames here are JSON string
    // as you should call json_encode($arrayOfFilenames)
    // in your php script (upload.php)
    var fileNames = xhr.responseText; 
  }
}

If you'd like consider using a simple library for AJAX requests, like axios. It's promise based HTTP client for the browser, really simple to use and saves you some time and effort cause you don't have to memorize all this stuff you and I have just written.

This is one approach, but I think you can use $_SESSION as well, and it's perfectly valid. My guess is you don't have logged in user at this point, so my idea is as follows:

  • put filenames into the $_SESSION

  • use db transactions - as @Marc B suggested - to connect files with
    user

  • if there were no errors just remove filenames from $_SESSION, if there was some, just redirect the user back to the form (possibly with some info what went wrong), and this way he doesn't have to reupload files, cause you have filenames still in $_SESSION

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the answer. But "upload.php" is called in the XMLHttpRequest API in javascript, how can i then get the result of post request?
I have modified my answer including this information.
"xhr.responseText" is exactly what i needed. I'll continue digging also in php sessions and see which one to use. Thanks for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.