Joseph Duffy
Joseph Duffy

Reputation: 4836

Pass uploaded file between PHP scripts

I've got a page where users can upload a HTML file for use as a theme. The HTML file has some checks performed on it before some options are displayed to the user. The user fills out the form in relation to the HTML file, and submits the form. However, due to the file in the temp folder being destroyed after the script has ended, I do not know how to get the HTML file once the form has been filled out and re-submitted short of making the user re-upload the file, which relies on them uploading the same file, and also makes them upload something twice, which is counter-intuitive and could be an issue with large files.
Here is the code (cut down to make it easier to read/understand). The form submits to itself, so the same PHP file is used for both "steps".

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // Form has been submitted
    $files = $_FILES['file'];
    <form method="POST">
        /* Options about the uploaded HTML file are generated using PHP and displayed here */
        <input type="submit">
    </form>
} else {
    ?>
    <form method="POST" enctype="multipart/form-data">
        <label for="file">Theme File(s)</label>
        <input type="file" name="file[]" multiple="multiple">
        <input type="submit">
    </form>
    <?php
}

I tried using <input type="file" name="file[]" multiple="multiple" value="<?php echo $files; ?> >, but this did not work, and would also require the user to re-upload the files, which could be any issue if the files get too big.
I was thinking there might be a way to pass the file internally, and have a check whether a file has been uploaded or passed to the script instead of <input type="file" name="file[]" multiple="multiple">, but I could not find a way to do that.

Upvotes: 3

Views: 3343

Answers (2)

DaveRandom
DaveRandom

Reputation: 88707

You need to create your own temporary file, and pass the name between your two scripts.

So for example, in your "first script" (i.e. when the file has first been uploaded) you would:

$uniqName = uniqid('upload_', TRUE);
$tmpFile = "/tmp/$uniqName.html";
move_uploaded_file($_FILES['file']['tmp_name'][0], $tmpFile);

And then when you generate the form from the result of this upload, you would add

<input type="hidden" name="uniqName" value="<?php echo $uniqName; ?>" />

...so that when you get to your "second script" (after the questionnaire form is submitted) you can access the file through:

$tmpFile = "/tmp/".basename($_REQUEST['uniqName']).".html";

Of course, this is subject to the possibility of people failing to submit to second form so you end up with "orphaned files" littering your temporary directory, so you will need to implement some form of check that deletes files after thet have been inactive for a certain amount of time - you can base this on the last modified time of the files.

EDIT

Here is an example of how you can randomly run a job to keep the /tmp dir tidy without a cron job:

$probabilityDivisor = 10; // 1/10 chance of running
$uploadTTLSecs = 1800; // 30 minutes

if (mt_rand(1, $probabilityDivisor) / $probabilityDivisor == 1) {
  foreach (glob('/tmp/upload_*') as $file) {
    // Iterate files matching the uniqids you generate
    if (time() - filemtime($file) >= $uploadTTLSecs) {
      // If file is older than $uploadTTLSecs, delete it
      unlink($file);
    }
  }
}

This operates in a similar way to the PHP session garbage collectors. Because of the simplicity of the operations, this should not adversely affect the user experience in any meaningful way.

Upvotes: 2

maximus 69
maximus 69

Reputation: 1458

You could try the following:

  1. Use move_uploaded_file() and move the file from the temp location to a permanent location on the server. Be sure to give the file your moving a unique name like 'file-' . time() . '.jpg' or something.

  2. Soon after uploading, register a Session variable and put the file name in it.

  3. After everything is over you could delete the file using unset()

Now the file is located safely on your server and you also have access to it via the session.

Hope this helps :)

Upvotes: 0

Related Questions