Skip to content

Instantly share code, notes, and snippets.

@asciito
Created February 3, 2024 20:51
Show Gist options
  • Save asciito/03db6f34c11b52357db2288f5639f835 to your computer and use it in GitHub Desktop.
Save asciito/03db6f34c11b52357db2288f5639f835 to your computer and use it in GitHub Desktop.
<?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>
@asciito
Copy link
Author

asciito commented Feb 3, 2024

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.

mkdir images

Then:

php -S 0.0.0.0:8080

and, just go to localhost:8080

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