Created
February 3, 2024 20:51
-
-
Save asciito/03db6f34c11b52357db2288f5639f835 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
session_start(); | |
/** | |
* Flash a message in the session, or get a message from the session | |
**/ | |
function flash(string $key, string $message = null) | |
{ | |
if (empty($message)) { | |
$message = $_SESSION[$key] ?? null; | |
unset($_SESSION[$key]); | |
return $message; | |
} | |
$_SESSION[$key] = $message; | |
} | |
if ($_SERVER['REQUEST_METHOD'] === 'POST') { | |
// Upload directory | |
define('UPLOAD_DIR', __DIR__ . DIRECTORY_SEPARATOR . 'images'); | |
try { | |
if ( | |
!isset($_FILES['image']['error']) || | |
is_array($_FILES['image']['error']) | |
) { | |
throw new RuntimeException('Invalid Parameters'); | |
} | |
$error = match ($_FILES['image']['error']) { | |
UPLOAD_ERR_OK => '', | |
UPLOAD_ERR_NO_FILE => 'No image sent.', | |
UPLOAD_ERR_INI_SIZE, | |
UPLOAD_ERR_FORM_SIZE => 'Exceeded filesize limit.', | |
default => 'Unknown error.', | |
}; | |
if (!empty($error)) { | |
throw new RuntimeException($error); | |
} | |
// ~2MB max only | |
if ($_FILES['image']['size'] > 2 * 1024 * 1024) { | |
throw new RuntimeException('Exceeded image size limit.'); | |
} | |
$finfo = new finfo(FILEINFO_MIME_TYPE); | |
if (false === $ext = array_search( | |
$finfo->file($_FILES['image']['tmp_name']), | |
[ | |
'gif' => 'image/gif', | |
'png' => 'image/jpeg', | |
'jpeg' => 'image/jpeg', | |
'webp' => 'image/webp', | |
], | |
true | |
)) { | |
throw new RuntimeException('The file is not an image.'); | |
} | |
if (!move_uploaded_file( | |
$_FILES['image']['tmp_name'], | |
sprintf( | |
"%s" . DIRECTORY_SEPARATOR . "%s.%s", | |
UPLOAD_DIR, | |
sha1_file($_FILES['image']['tmp_name']), | |
$ext | |
) | |
)) { | |
throw new RuntimeException('Failed to move uploaded image.'); | |
} | |
flash('success', 'The image was uploaded'); | |
} catch (RuntimeException $e) { | |
flash('error', $e->getMessage()); | |
} | |
header("Location: /"); | |
exit(); | |
} | |
?> | |
<!DOCTYPE html> | |
<html class="w-screen h-screen"> | |
<haad> | |
<title>File upload</title> | |
<style> | |
*, | |
*::before, | |
*::after { | |
box-sizing: border-box; | |
} | |
html { | |
font-size: 62.5%; | |
} | |
body { | |
font-family: Arial, Helvetica, sans-serif; | |
font-size: 1.6rem; | |
margin: 0; | |
} | |
input { | |
border: none; | |
font-size: 1.4rem; | |
} | |
/** UTILITIES **/ | |
.w-screen { | |
width: 100vw; | |
} | |
.h-screen { | |
height: 100vh; | |
} | |
.w-full { | |
width: 100%; | |
} | |
.h-full { | |
height: 100%; | |
} | |
.mx-auto { | |
margin: 0 auto; | |
} | |
/** OTHRES **/ | |
.form-container { | |
max-width: 500px; | |
width: 100%; | |
border: 1px solid #e2e2e2; | |
border-radius: 0.4rem; | |
background-color: white; | |
padding: 3rem 2.5rem; | |
margin-top: 4rem; | |
} | |
.form-container .form { | |
display: flex; | |
flex-wrap: wrap; | |
} | |
.form *~*:not([hidden]) { | |
margin-top: 1.2rem; | |
} | |
.form .form-group { | |
display: flex; | |
flex-wrap: wrap; | |
width: 100%; | |
} | |
.form-group input { | |
border: 1px solid #e2e2e2; | |
border-radius: 0.4rem; | |
padding: 1.4rem 2.4rem; | |
width: 100%; | |
} | |
.form-group input::placeholder { | |
font-family: Arial, Helvetica, sans-serif; | |
color: #e3e3e3; | |
} | |
.flash-message { | |
background-color: #e4e4e4; | |
border: 1px solid #e4e4e4; | |
border-radius: 0.4rem; | |
margin: 2rem 0 0 0; | |
padding: 1rem 2rem; | |
font-size: 1.4rem; | |
text-align: center; | |
} | |
.flash-message.error { | |
border-color: #ff7878; | |
background-color: #ff7878; | |
color: white; | |
} | |
.flash-message.success { | |
border-color: #78ff7f; | |
background-color: #78ff7f; | |
color: #131313; | |
} | |
</style> | |
</haad> | |
<body class="w-screen h-screen"> | |
<main class="w-full h-full"> | |
<div class="form-container mx-auto"> | |
<form class="form" method="POST" enctype="multipart/form-data"> | |
<div class="form-group"> | |
<label for="image">Upload Image</label> | |
<input type="file" id="image" name="image"> | |
</div> | |
<button type="submit">Submit</button> | |
</form> | |
<?php if (!empty($_SESSION)) : ?> | |
<?php if ($message = flash('error')) : ?> | |
<p class="flash-message error"> | |
<?= $message ?> | |
</p> | |
<?php else : ?> | |
<p class="flash-message success"> | |
<?= flash('success'); ?> | |
</p> | |
<?php endif; ?> | |
<?php endif; ?> | |
</div> | |
</main> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
File Upload
This gist is just for fun, and the intent of this is for learning purposes. The reason is that A LOT of developers (including me) are used to working with frameworks. This is not bad; it's just that we tend to forget the very basics of the language we use all day. In this case, it's how to upload an image.
At least for me, this is a bad habit because we cannot solve complicated problems without relying on a framework or library, and sometimes the solutions are way easier. But we prefer not to bother too much, and download a package or use a framework is our way to go. I'm not against any framework or package (I love Laravel) because, as you can see, my code is not perfect; it has its own flaws, like input validation, XSS, etc., etc.
Feel free to judge my code, comment, contribute, or anything else, but be polite always, we're programmers.
Disclaimer
DO NOT USE THIS CODE IN PRODUCTION, THIS GIST IS FOR LEARNING PURPOSES
Instructions
To test/work with the gist, use the included PHP server, but first create a a folder called
images
on the same level where you put this code.Then:
and, just go to
localhost:8080