Welcome to a quick tutorial on how to create a very simple PHP gallery. Tired of all those complicated gallery plugins on the Internet?
Creating a no-database PHP image gallery is as easy as getting a list of image files using glob()
and outputting them in HTML.
$images = glob("PATH/GALLERY/*.{jpg,jpeg,gif,png,bmp,webp}", GLOB_BRACE);
foreach ($images as $i) { echo "<img src='gallery/". rawurlencode(basename($i)) ."'>"; }
Yep, just like that in 1 minute. But how does this work exactly? Let us walk through a no gimmicks image gallery in this guide – Directly reads image files from a folder, no database required. Read on!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TLDR – QUICK SLIDES
Fullscreen Mode – Click Here
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
QUICK NOTES
1a-gallery.php
– Simple gallery without image caption.2a-caption-gallery.php
– Alternate version with image caption.
SCREENSHOT
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
PHP SIMPLE IMAGE GALLERY
All right, let us now get into creating the very basic image gallery – Requiring only a few lines of PHP code, it’s so simple that you will laugh all the way to the moon.
STEP 1) GET IMAGES & OUTPUT AS HTML
<!-- (A) CSS & JS -->
<link href="1b-gallery.css" rel="stylesheet">
<script src="1c-gallery.js"></script>
<div class="gallery"><?php
// (B) GET IMAGES IN GALLERY FOLDER
$dir = __DIR__ . DIRECTORY_SEPARATOR . "gallery" . DIRECTORY_SEPARATOR;
$images = glob("$dir*.{jpg,jpeg,gif,png,bmp,webp}", GLOB_BRACE);
// (C) OUTPUT IMAGES
foreach ($images as $i) {
printf("<img src='gallery/%s'>", rawurlencode(basename($i)));
}
?></div>
Yep, that’s all to the gallery page. As in the introduction, all we are doing here is –
- (B) Get a list of image files from the gallery folder using
glob()
. - (C) Output them as HTML
<img>
tags in<div class="gallery">
.
STEP 2) CSS GRID LAYOUT
/* (A) GALLERY WRAPPER */
/* (A1) BIG SCREENS - 3 IMAGES PER ROW */
.gallery {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
max-width: 1200px;
margin: 0 auto; /* horizontal center */
}
/* (A2) SMALL SCREENS - 2 IMAGES PER ROW */
@media screen and (max-width: 640px) {
.gallery { grid-template-columns: repeat(2, 1fr); }
}
/* (B) THUMBNAILS */
.gallery img {
width: 100%;
height: 200px;
object-fit: cover; /* fill | contain | cover | scale-down */
border: 1px solid #cdcdcd;
cursor: pointer;
}
/* (C) FULLSCREEN IMAGE */
.gallery img.full {
position: fixed;
top: 0; left: 0; z-index: 999;
width: 100vw; height: 100vh;
object-fit: contain; /* fill | contain | cover | scale-down */
border: 0;
background: #fff;
}
Of course, we are not so “barbaric” to throw out raw images without cosmetics.
- (A1)
display: grid; grid-template-columns: repeat(3, 1fr);
will lay out in a “nice gallery format” of 3 images per row. - (A2) On smaller screens, change the layout to 2 images per row.
- (B)
width: 100%; height: 200px;
to set a “uniform dimension” on all images. - (B)
object-fit
is the “image scale to fit” behavior. Change this and see for yourself, choose one that you like. - (C) When the user clicks on an image, we toggle a
.full
CSS class on it. Long story short,.full
simply sets the image to cover the entire screen.
STEP 3) JAVASCRIPT TOGGLE FULLSCREEN IMAGE
window.addEventListener("DOMContentLoaded", () => {
// (A) GET ALL IMAGES
var all = document.querySelectorAll(".gallery img");
// (B) CLICK ON IMAGE TO TOGGLE FULLSCREEN
if (all.length>0) { for (let img of all) {
img.onclick = () => { img.classList.toggle("full"); };
}}
});
- On window load, get all the gallery images.
- On clicking the image, toggle the
.full
CSS class – This will show the image in fullscreen.
EXTRA BITS & LINKS
That’s it for all the code. Here are some extras that may be useful to you.
EXTRA) ANIMATION
/* (D) OPTIONAL ANIMATION */
.gallery { overflow-x: hidden; }
.gallery img { transition: all 0.3s; }
Long gone is the Stone Age of the Internet. To animate the fullscreen toggle, we only need to add a CSS transition
. Beware though, this is not friendly for slow mobile devices… But with mobile devices becoming powerful these days, it should not be a problem anyway.
EXTRA) FILENAME AS IMAGE CAPTION
foreach ($images as $i) {
$img = basename($i);
$caption = substr($img, 0, strrpos($img, "."));
printf("<figure><img src='gallery/%s'><figcaption>%s</figcaption></figure>",
rawurlencode($img), $caption
);
}
Since there is no database, there is nowhere we can store the captions. But we can still use the file name as the caption of the images – This is just a small modification to the PHP to also output the <figcaption>
.
EXTRA) SORTING THE IMAGES
usort($images, function ($file1, $file2) {
return filemtime($file2) <=> filemtime($file1);
});
usort($images, function ($file1, $file2) {
return filemtime($file1) <=> filemtime($file2);
});
sort($images); // low to high
rsort($images); // high to low
EXTRA) MULTIPLE CATEGORIES & FOLDERS
<h1>CATEGORY A</h1>
<div class="gallery"><?php
$images = glob(FOLDER A);
foreach ($images as $i) { printf("<img src='FOLDER A...'>"); }
?></div>
<h1>CATEGORY B</h1>
<div class="gallery"><?php
$images = glob(FOLDER B);
foreach ($images as $i) { printf("<img src='FOLDER B...'>"); }
?></div>
Just put your images into different category folders, and repeat the “get list of files and output HTML”. Of course, this is good as a “quick fix” only. Not recommended if you have a dozen folders.
EXTRA) INCLUDE VIDEOS
// (A) GET IMAGES & VIDEOS
$media = glob("$dir*.{jpg,jpeg,gif,png,bmp,webp,avi,mp4}", GLOB_BRACE);
// (B) OUTPUT HTML
foreach ($media as $i) {
$parts = pathinfo($i);
if ($parts["extension"]=="avi" || $parts["extension"]=="mp4") {
printf("<video src='gallery/%s' controls></video>", basename($i));
} else { printf("<img src='gallery/%s'>", basename($i)); }
}
But the problem is – How to deal with video playback. Play while in the thumbnail size? Or engage in full-screen mode first? Check out the video gallery tutorial below if you want more.
COMPATIBILITY CHECKS
- Arrow Functions – CanIUse
- CSS Grid – CanIUse
- Transition – CanIUse
This simple gallery will work on any modern browser.
USEFUL LINKS
- Simple PHP Video Gallery – Code Boxx
- Very Simple Responsive Image Gallery (Pure HTML CSS) – Code Boxx
- Simple Javascript CSS Slideshow – Code Boxx
TUTORIAL VIDEO
INFOGRAPHIC CHEAT SHEET

THE END
Thank you for reading, and we have come to the end of this short tutorial. I hope that it has helped you to create a better (and simpler) image gallery, and if you have anything to share with this guide, please feel free to comment below. Good luck and happy coding!
All I see when using this code on my main page is:
“, rawurlencode(basename($i))); } ?>
https://code-boxx.com/how-to-run-php-scripts/
Where could I add a line of code to only load a certain number of images? I feel like it’s probably a pretty simple deal.
For example I’d like to only show the first 50 newest images, sorted newest first.
Sort by newest first, then slice 50 entries.
https://www.php.net/manual/en/function.array-slice.php
Thanks. I actually got it a different way. Right before the foreach line I set a variable called counter=1. At the end of the foreach block I increment the counter, and then if the counter=50 or whatever I do a break();
Not sure if that’s ideal, but it works. 🙂
I’m working on passing the number of images to view from a $_GET variable now too.
Thanks!
Thank you, for your very good Gallery system. I have a situation I don’ know how to handle? I am using XAMPP on a win 10 system. One of the branches(directory) of of htdocs holds the gallery code(s). That branch has maybe ten branches of it. And each of those ten have another ten or so branches. In a few cases there would be additional branches. The images would be on the outer branches. How can I use one copy of the code to reach any one of the sets of images (only one set of images at a time, no mixing.) When ready to view a new set of images, I have a good menu system to feed the new directory to the code. Your suggestions would be very helpful.
See “MULTIPLE CATEGORIES AND FOLDERS” above. But otherwise, sorry, I cannot offer free consultations for personal projects and deployments. Good luck.
https://code-boxx.com/faq/#help “Help on a deeper level”
How to get Next and Previous links in full screen mode?
How can I implement them?
1) Add hidden back and next buttons to
<div class="gallery">
2) On selecting an image, set
<div class="gallery full">
and<img class="full">
3) Show
<div class="gallery full">
in fullscreen instead – Hide all images except<img class="full">
, also show the last/next buttons.4) On last/next, set
class="full"
on the last/next image accordingly.Good luck.
Foremost, thanks for making this guide. It’s really to the point and helpful.
I only found one issue with the js, but I have the solution in case others get stuck.
Here is the corrected code:
EDIT BY WS : It’s Sep 2022, and Apple is still not supporting fullscreen mode properly on iPhone. Switched to use a CSS solution instead.
lazy srcoll would be very needed addition
1) Change the gallery to load via AJAX instead.
2) Count the total number of images.
3) Load only N images per page.
4) Then, https://code-boxx.com/infinite-page-scroll/
Good luck.
Hi WS Toh,
I really like your php gallery. I want to ask if you can help me with modifying your js file so it shows the full image when I click on the thumbnail, or so there are scroll bars to allow scrolling around in the pic?
My issue is, I am using images from my DJI Mavic drone and their typical sizes are 5472px by 3648px. So, when I click on the thumbnail with your js file as it is now, the center of the image fills the screen, but I cannot view the rest of the image.
Any help is GREATLY appreciated.
Best regards,
Greg
Do some research on HTML and CSS overflow on your own. Good luck.
https://code-boxx.com/faq/#help “Answers all over the Internet”
thank you.
hello WS Toh,
I find this script very useful in an educational site where Parents and Teachers can upload and view images together, but is it possible to display a download button and a delete button over each image? (although delete should only be possible for the user who uploaded the image!)
There is no database, no user system in place. How are you going to determine which photo belongs to who?
I was thinking of allowing the deletion only during the present session and only for what the respective user uploaded;
on the other hand the download could be done by anyone, anytime …
OK. Good luck with your project.
https://code-boxx.com/faq/#help
https://code-boxx.com/position-text-over-image-html/
https://code-boxx.com/force-download-php/
https://code-boxx.com/sessions-in-php/