4

I'm trying to upload a file and rename it if it already exists. The way I want i to do is that when det same file uploads the name just adds 1, then 2, then 3, and so on.

Example: If file "file" exists, the new file should be "file1", then the next one "file2".

I've seen some examples on the net, but nothing that I could see fit to my code (noob)

This is my code now:

$id = $_SESSION['id'];
$fname = $_FILES['dok']['name'];
if ($_FILES['dok']['name'] !=""){
// Checking filetype
if($_FILES['dok']['type']!="application/pdf")     {die("You can only upload PDF files");}

// Checking filesize
if ($_FILES['dok']['size']>1048576) {die("The file is too big. Max size is 1MB");}

// Check if user have his own catalogue
if (file_exists("filer/".$id."/")) {
// Moving the file to users catalogue
move_uploaded_file($_FILES['dok']['tmp_name'],"filer/".$id."/".$fname);}

//If user don't have his own catalogue 
else {
// Creates new catalogue then move the file in place
mkdir("filer/".$id);
move_uploaded_file($_FILES['dok']['tmp_name'],"filer/".$id."/".$fname);   } }

Can somebody help me where I can put in code that solves this problem? Big thank you!

Aromefraise
  • 45
  • 1
  • 1
  • 7
  • Have you tried anything yourself? – jeroen May 30 '14 at 21:42
  • Your code is highly dangerous. You're directly using the **USER** provided `['name']` paramter as the final location of the file on your server. A malicious user can embed pathing information and use your script to scribble ANY file they want on the server. Your `['type']` check is **NOT** security. It's useless. mime types are trivial to forge. – Marc B May 30 '14 at 21:43
  • Yes, I actually tried bunch, but hasn't make it work as I'm quite new, I strangle to edit code and make it fit with mine.. – Aromefraise May 30 '14 at 21:53

3 Answers3

7
$id = $_SESSION['id'];
$fname = $_FILES['dok']['name'];
if ($_FILES['dok']['name'] !=""){
    // Checking filetype
    if($_FILES['dok']['type']!="application/pdf") {
        die("You can only upload PDF files");
    }
    // Checking filesize
    if ($_FILES['dok']['size']>1048576) {
        die("The file is too big. Max size is 1MB");
    }

    if(!is_dir("filer/".$id."/")) {
        mkdir("filer/".$id); 
    }

    $rawBaseName = pathinfo($fname, PATHINFO_FILENAME );
    $extension = pathinfo($fname, PATHINFO_EXTENSION );
    $counter = 0;
    while(file_exists("filer/".$id."/".$fname)) {
        $fname = $rawBaseName . $counter . '.' . $extension;
        $counter++;
    };

    move_uploaded_file($_FILES['dok']['tmp_name'],"filer/".$id."/".$fname);  

} 

But don't forget to secure your script (eg see comment of Marc B above) and maybe you could optimize some more ;-)

SomeoneYouDontKnow
  • 1,289
  • 10
  • 15
  • First time it good, adds an 0, but the second time it's just loading, waiting for localhost.. This is the error: Fatal error: Maximum execution time of 30 seconds exceeded in ( while(file_exists("filer/".$id."/".$fnavn)) { $fnavn = $rawBaseName . $counter . '.' . $extension;}; ) – Aromefraise May 30 '14 at 22:15
1

so if folder exists:

file_exists("filer/".$id."/")

check if file exists

file_exists("filer/".$id."/".$fname)

and then if it does,

$fname = $fname . "(1)" // or some appending string

So in the end you change your code to:

// Check if user have his own catalogue
if (file_exists("filer/".$id."/")) {
    while (file_exists("filer/".$id."/".$fname)) // Now a while loop
        $fname = "copy-" . $fname; // Prepending "copy-" to avoid breaking extensions

    // Moving the file to users catalogue
    move_uploaded_file($_FILES['dok']['tmp_name'],"filer/".$id."/".$fname);}

//If user don't have his own catalogue 
else {
Uxonith
  • 1,602
  • 1
  • 13
  • 16
  • This made the filename get a (1) after it, but then it stops there, how to make it follow up? Second, now the filetype changes, as it is an .pdf file.. The name who is originally "file" gets now "file.pdf1", this makes it unreadable – Aromefraise May 30 '14 at 21:52
  • I think that covers both of the issues – Uxonith May 30 '14 at 22:02
  • This may cause issues if there is going to be a mass amount of duplicates as the file name will get massive. I don't know what OS limits are for file names but I think they exist on most OS's. A lot of services avoid this complication by using a timestamp/UUID in addition to the file name. – Uxonith May 30 '14 at 22:04
1
<form action="test.php" method="post" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="submit" value="Upload File" name="submit">
</form>

<?php
$id = $_SESSION['id'];
$fname = $_FILES['fileToUpload']['name'];
 // Checking filesize
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], "uploads/".$id."/".$fname)) {
    echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
}else {
    echo "Sorry, there was an error uploading your file.";
}
// Check file size$
if ($_FILES['fileToUpload']['size']>1048576) {
    die("The file is too big. Max size is 1MB");
}
if(!is_dir("uploads/".$id."/")) {
    mkdir("uploads/".$id); 
}

$rawBaseName = pathinfo($fname, PATHINFO_FILENAME );
$extension = pathinfo($fname, PATHINFO_EXTENSION );
$counter = 0;
while(file_exists("uploads/".$id."/".$fname)) {
    $fname = $rawBaseName . $counter . '.' . $extension;
    $counter++;
};

move_uploaded_file($_FILES['fileToUpload']        ['tmp_name'],"uploads/".$id."/".$fname);  
?>
  • 1
    Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others. – zuazo Dec 31 '16 at 08:00