Skip to content

Instantly share code, notes, and snippets.

@daveh
Last active October 10, 2024 20:05
Show Gist options
  • Save daveh/6934c8d5cd7cd4b0afa1f15ae4799484 to your computer and use it in GitHub Desktop.
Save daveh/6934c8d5cd7cd4b0afa1f15ae4799484 to your computer and use it in GitHub Desktop.
PHP File Uploads (code to accompany https://youtu.be/K_W5ZqwEcqs)
<!DOCTYPE html>
<html>
<head>
<title>PHP File Uploads</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
</head>
<body>
<h1>PHP File Uploads</h1>
<form method="post" enctype="multipart/form-data" action="process-form.php">
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="1048576"> -->
<label for="image">Image file</label>
<input type="file" id="image" name="image">
<label for="file2">Another file</label>
<input type="file" name="file2" id="file2">
<button>Upload</button>
</form>
</body>
</html>
<?php
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
exit('POST request method required');
}
if (empty($_FILES)) {
exit('$_FILES is empty - is file_uploads set to "Off" in php.ini?');
}
if ($_FILES["image"]["error"] !== UPLOAD_ERR_OK) {
switch ($_FILES["image"]["error"]) {
case UPLOAD_ERR_PARTIAL:
exit('File only partially uploaded');
break;
case UPLOAD_ERR_NO_FILE:
exit('No file was uploaded');
break;
case UPLOAD_ERR_EXTENSION:
exit('File upload stopped by a PHP extension');
break;
case UPLOAD_ERR_FORM_SIZE:
exit('File exceeds MAX_FILE_SIZE in the HTML form');
break;
case UPLOAD_ERR_INI_SIZE:
exit('File exceeds upload_max_filesize in php.ini');
break;
case UPLOAD_ERR_NO_TMP_DIR:
exit('Temporary folder not found');
break;
case UPLOAD_ERR_CANT_WRITE:
exit('Failed to write file');
break;
default:
exit('Unknown upload error');
break;
}
}
// Reject uploaded file larger than 1MB
if ($_FILES["image"]["size"] > 1048576) {
exit('File too large (max 1MB)');
}
// Use fileinfo to get the mime type
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->file($_FILES["image"]["tmp_name"]);
$mime_types = ["image/gif", "image/png", "image/jpeg"];
if ( ! in_array($mime_type, $mime_types)) {
exit("Invalid file type");
}
// Replace any characters not \w- in the original filename
$pathinfo = pathinfo($_FILES["image"]["name"]);
$base = $pathinfo["filename"];
$base = preg_replace("/[^\w-]/", "_", $base);
$filename = $base . "." . $pathinfo["extension"];
$destination = __DIR__ . "/uploads/" . $filename;
// Add a numeric suffix if the file already exists
$i = 1;
while (file_exists($destination)) {
$filename = $base . "($i)." . $pathinfo["extension"];
$destination = __DIR__ . "/uploads/" . $filename;
$i++;
}
if ( ! move_uploaded_file($_FILES["image"]["tmp_name"], $destination)) {
exit("Can't move uploaded file");
}
echo "File uploaded successfully.";
@slMiSFiT
Copy link

thanks

@rich-potter
Copy link

question - this part -

// Use fileinfo to get the mime type
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->file($_FILES["image"]["tmp_name"]);

$mime_types = ["image/gif", "image/png", "image/jpeg"];

if ( ! in_array($_FILES["image"]["type"], $mime_types)) {
exit("Invalid file type");
}

shouldn't it be

if (!in_array($mime_type, $mime_types)) {
exit("Invalid file type");
}

@daveh
Copy link
Author

daveh commented Jul 12, 2024

@rich-potter Yes, you're right, well spotted! Thanks for letting me know, I've updated the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment