willy
willy

Reputation: 23

Uploading multiple files with php without overwriting previous file

So i am trying to upload multiple files at once, but each time i do it is only uploading the last file in the loop for each file upload that i try to do. Ultimately it is only uploading one file to my server that multiple points in my database are referencing.

I have tried executing the upload file function outside of the loop with independent functions and variables but it is still doing it.

My code:

<?php $image_number = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
$image_allowed = array('jpg', 'jpeg', 'gif', 'png');
if (empty($errors) === true) {
  foreach ($image_number as $value) {
    if (isset($_FILES['story_image_' . $value]) === true) {
        if (empty($_FILES['story_image_' . $value]['name']) === false) {
            if (in_array(strtolower(end(explode('.', $_FILES['story_image_' . $value]['name']))), $image_allowed) === false) {
                $errors[] = 'Incorrect file type for \'Story image ' . $value . '\'. Allowed file types: ' . implode(', ', $image_allowed);
            } else if ($_FILES['story_image_' . $value]['size'] > 1048576) {
                $errors[] = 'Story image ' . $value . '\'s file size may not exceed 1 MB, or 1048576 Bytes.';
            }
        }
    }
  }
}

foreach ($image_number as $value) {
    if ($_POST['removeImage' . $value] === 'on') {
        remove_story_image($story_data['story_id'], $value, $story_data['story_image_' . $value]);
    } else {
        if (isset($_FILES['story_image_' . $value]) === true) {
            if (empty($_FILES['story_image_' . $value]['name']) === false) {


                $file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                $movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                move_uploaded_file($_FILES['story_image_' . $value]['tmp_name'], $movefile_path);
                mysql_query("UPDATE `stories` SET `story_image_" . $value . "` = '" . mysql_real_escape_string($file_path) . "' WHERE `story_id` = " . $story_data['story_id']);
            }
        }   
    }
}
?>

I have checked my form, and all of the file fields' names that are independently named and match. It is not a syntax issue because the first loop checking for errors works flawlessly. its only when i try to upload the file does it start to overwrite.

Can anyone enlighten me? ( i am a pretty big noob so please try to keep it in newb speak)

***** Update ***********

So I have solved the problem now and below is the working code:

foreach ($image_number as $value) {
    if ($_POST['removeImage' . $value] === 'on') {
        remove_story_image($story_data['story_id'], $value, $story_data['story_image_' . $value]);
    } else {
        if (isset($_FILES['story_image_' . $value]) === true) {
            if (empty($_FILES['story_image_' . $value]['name']) === false) {


                $file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                $movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                if (file_exists($movefile_path) === true) {
                    $file_path = '/cdsite/images/storyimages/' . substr(md5(time()), 0, 10) . substr(md5(rand()),0,10) . '.' . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));
                    $movefile_path = $_SERVER['DOCUMENT_ROOT'].$file_path;
                }
                move_uploaded_file($_FILES['story_image_' . $value]['tmp_name'], $movefile_path);
                mysql_query("UPDATE `stories` SET `story_image_" . $value . "` = '" . mysql_real_escape_string($file_path) . "' WHERE `story_id` = " . $story_data['story_id']);
            }
        }   
    }
}

For those who may run into a similar problem in the future and need a simple explanation, which i so often appreciate when others provide one, here is a brief explanation of what the issue was and how i fixed it.

The problem was i was md5 hashing the same time when i was iterating through the loop, rewriting over the same file name with this line of code:

$movefile_path = $_SERVER['DOCUMENT_ROOT']."/cdsite/images/storyimages/" . substr(md5(time()), 0, 10) . "." . strtolower(end(explode('.', $_FILES['story_image_' . $value]['name'])));

As you notice i have two file paths. This isn't to confuse anyone, it is to allow me to upload a absolute path to the database that html can reference later ($file_path) and to have an absolute path that php can work with to upload the file ($movefile_path).

To fix the problem i had the loop check to see if the file already exists and, if it did, just added a random string that was md5 hashed following the md5 hashed timestamp to make a new unique file name. I used the $movefile_path file path to check to see if the file existed because that is the path php can use.

I also made sure to include the updated $file_path variable in the updated $movefile_path, otherwise re-hashing the random string would have given me a different file name for html to reference from my database than the actual file name that php uploaded.

Upvotes: 1

Views: 1548

Answers (1)

Nathan van der Werf
Nathan van der Werf

Reputation: 332

You should rename the file you are uploading, never trust user input... You could put a unix timestamp or unique id behind the image name

Upvotes: 1

Related Questions