开发者

Rename uploaded files to avoid overwriting

I have this simple script which works fine, but currently overwrites files with duplicate names. How can I avoid this?

<?php
   // Configuration - Your Options
    $allowed_filetypes = array('.mp3'); // These will be the types of file that will pass the validation.
    $max_filesize = 1048576; // Maximum filesize in BYTES (currently 0.5MB).
    $upload_path = './uploads/'; // The place the files will be uploaded to (currently a 'files' directory).

    $filename = $_FILES['userfile']['name']; // Get the name of the file (including file extension).
    $ext = substr($filename, strpos($filename,'.'), strlen($filename)-1); // Get the extension from the filename.

    if(!in_array($ext,$allowed_filetypes))

        header('Location: http://www.website.com/five/error');

    if(filesize($_FILES['userfile']['tmp_name']) > $max_filesize)

        header('Location: http://www.website.com/five/error');

    if(!is_writable($upload_path))

        header('Location: http://www.website.com/five/error');

    if(move_uploaded_file($_FILES['userfile']['tmp_name'],$upload_path . $filename))

//         echo 'Your file upload was successful, view the file <a href="' . $upload_path . $filename . '" title="Your File">here</a>'; // It worked.
        header('Locati开发者_C百科on: http://www.website.com/five/sent');

    else

        header('Location: http://www.website.com/five/error');

?>


Add an if (file_exists($upload_path.$filename)) before you upload, and set $filename to something else if it does.


One option is to use a database to store the original names, along with a unique id.

Then you can save the file as whatever unique name you want.

  • Use just the id... file = 1
  • Use the id and extension = 1.mp3
  • Use a combination of the id and name = 1_name_of_file.mp3
  • Or any other unique naming option.

Then you use php to serve the files. Setting the header with the original file name.

Users would not be aware of how you are storing the file. Multiple files with the same name could be uploaded and downloaded with that name, but stored uniquely on the server.

<?php

$actualFile = './uploads/'.$id;

// Can use some smarts to determine the mime type here
header('Content-type: application/force-download');

// The user will be prompted to save it as the filename given here.
header('Content-Disposition: attachment; filename="'.$originalName.'"');
header("Content-Length: ".filesize($actualFile));


// The actual file on the server
readfile($actualFile);
?>

There are also a number of other header options you can set for caching and so on.

http://php.net/manual/en/function.header.php

Fileinfo is a good extension for determining mimetypes

http://www.php.net/manual/en/function.finfo-file.php


Use your own filename instead of the original.

This could for example be generated via uniqid()


store the file with a hash as the name, and store the original filename in a database/flat file along with the hash.

if you want to use flat files it could just be that the user file gets stored as .dat and the info about the file is stored as either .json or .xml or even just a serialized PHP object if you prefer.

also, your file-extension detecting logic fails as soon as the filename has more than one dot (period) in the name.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜