PHP: Prevent uploads from being overwitten

The following PHP file upload script makes the filename server-friendly, checks for filesize limitations, makes the filename unique so it doesn’t overwrite existing files (while using a sane naming scheme rather than simply using random generation & hoping for the best, lol), and outputs the final filename/location when finished.

$file = basename($_FILES['file']['name']); // Get the uploaded file's filename (input's name being set to "file")
$file = utf8_decode($file); // Convert to utf8
$file = strtr($file, utf8_decode("\'ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝÑñàáâãäåçèéêëìíîïðòóôõöùúûüýÿ"), "--AAAAAACEEEEIIIIOOOOOUUUUYNnaaaaaaceeeeiiiioooooouuuuyy"); // Replace special characters
$file = preg_replace('/( +)/i', '_', $file); // Replace spaces
$file = strtolower($file); // Make lowercase
$original_file = $file; // Save this as a reference

$size = $_FILES['file']['size']; // Get filesize
if($size>52428800){ // Check if filesize is greater than a specified amount
echo "error file size > 50 MB"; // Output error message
unlink($_FILES['file']['tmp_name']); // Clean up upload
exit; // Don't bother to run any more code
}

$file_i = 1; // Prep the number that'll be appended when there's an existing file
function prevent_overwrite(){
global $file_i,$file,$original_file; // Pull in our external variables
if(file_exists($file)){ // Check for existing file
$parts = explode('.',$file); // Blow apart
$parts[0] = $parts[0].$file_i; // Add incremental number after filename
$file = $parts[0].'.'.$parts[1]; // Join filename & extension back together
if(file_exists($file)){ // If it still has an existing counterpart
$file_i++; // Increase the number
$file = $original_file; // Revert back to the filename w/o the number (so they don't stack up so it ends up being "filename6.jpg" instead of "filename123456.jpg")
prevent_overwrite(); // Run it again
}
}
}
prevent_overwrite(); // Run this to prep to filename to account for the files already on the server

if(move_uploaded_file($_FILES['file']['tmp_name'], $file)){ // Try to upload the file
echo $file; // If successful, output the file's final location & filename
}else{
echo "error ".$_FILES['file']['error']." --- ".$_FILES['file']['tmp_name']." %%% ".$file."($_FILES['file']['size'])"; // Provide an error message
}

Hopefully somebody out there finds this useful. I provided more than what’s necessary for simply preventing uploads from being overwritten, but you can take the parts that you need and possibly take some stuff that you find useful.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.