如何处理文件上传名称

I'm trying to handle file uploads and now I face a dilemma. I have two options that I actually think about using when handling file name:

Option 1:

move_uploaded_file($_FILES['pdf']['tmp_name'], sprintf('./uploads/%s.%s', sha1_file($_FILES['pdf']['tmp_name']),$ext

Option 2:

move_uploaded_file($_FILES['pdf']['tmp_name'], sprintf('./uploads/%s.%s', "name_$date", $ext

First will generate hash with sha1_file which doesn't look pretty (and I would like to get that uploaded file name from DB and show it on page) but prevents multiple same file uploads.

Second gets a nice looking file name but doesn't prevent duplicates (file_exists seems to recognize duplicate but I couldn't stop move_upload_file)

What would you suggest me to do to get nice file name without file upload duplicates?

Maybe a simple solution: You can create a temporary directory with the name of the sha1 hash and put in the filenames with their original name.

This way, multi file uploads will go to different directories if they are different, but you will keep the original file name.

Example:

$uploadDir = "/your upload dir";
$contentHash = sha1_file($_FILES['pdf']['tmp_name']);
$tmpDir = $uploadDir . DIRECTORY_SEPARATOR . $contentHash;
mkdir($tmpDir, 0777); 
// add filename validation before storing it! 
$fileName = $tmpDir . DIRECTORY_SEPARATOR . $_FILES['pdf']['name'];
move_uploaded_file($_FILES['pdf']['tmp_name'], $fileName); 

You will wind up with a directory structure like this:

  • 01BADCOFFEE123
    • test.pdf
  • (some other hash)
    • test.pdf
  • ...

to later iterate the files, just use a recursive directory iterator:

$uploadDir = "/your upload dir";
$fileIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($uploadDir), \RecursiveIteratorIterator::LEAVES_ONLY);

No need to store anything in the database.

Add your db record id to your file name that will looks good and mean it.