2 Steps Very Simple PHP Gallery (From Folder No Database)

INTRODUCTION

NO GIMMICKS IMAGE GALLERY

Welcome to a step-by-step tutorial on how to create a very simple PHP gallery. Tired of all those “complicated” gallery plugins on the Internet? Actually, creating a raw basic image gallery is as easy as getting the list of images and outputting them in HTML.

  • $dir = “PATH/TO/GALLERY”;
  • $images = glob($dir . “*.{jpg,jpeg,gif,png,bmp,webp}”, GLOB_BRACE);
  • foreach ($images as $i) { printf(“<img src=’gallery/%s’>”, basename($i)); }

Yep. Just like that in 10 minutes. But how does this work exactly? This guide will show you how to create a no gimmicks image gallery – Directly reads image files from a folder, and with no database required at all. 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.

 

 

 

PREAMBLE

DOWNLOAD & NOTES

First, here is the download link to the source code as promised.

 

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.

 

FOLDERS

Here is a quick introduction to how the folders are being organized in the zip file.

  • gallery Where to store all the images.
  • thumbnail Used by the script to generate thumbnails automatically.

 

QUICK NOTES

  • No database – Just download and unzip into your project folder.
  • There are 3 different versions in the zip file.
    • 1-basic.php – The simplest version that just reads from the gallery folder and creates a flat gallery.
    • 2-box.php – Improved version. Creates a gallery, and also a “click to enlarge” on the images.
    • 3-thumbnail.php – Even more improved version. Automatically generates thumbnails as well.

If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

 

STEP 1

THE RAW BASIC GALLERY

Let us start by creating a very basic skeleton gallery – Requiring only a few lines of PHP code, some HTML, and CSS… So simple that you will laugh all the way to the moon.

 

THE PHP & HTML

1-basic.php
<!DOCTYPE html>
<html>
  <head>
    <title>Very Simple PHP gallery</title>
 
    <!-- (A) GALLERY CSS -->
    <link href="1-basic.css" rel="stylesheet">
  </head>
  <body>
    <!-- (B) GALLERY -->
    <div class="gallery"><?php
    // (B1) READ FILES FROM THE GALLERY FOLDER
    $dir = __DIR__ . DIRECTORY_SEPARATOR . "gallery" . DIRECTORY_SEPARATOR;
    $images = glob($dir . "*.{jpg,jpeg,gif,png,bmp,webp}", GLOB_BRACE);
 
    // (B2) OUTPUT IMAGES 
    foreach ($images as $i) {
      printf("<img src='gallery/%s'/>", basename($i));
    }
    ?></div>
  </body>
</html>

Yep, that’s all to the gallery. All we are doing here is to get a list of image files using glob from the gallery folder first, then throw them into a <div> gallery container.

 

 

THE CSS

1-basic.css
/* (A) THUMBNAILS */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, auto); /* 3 ITEMS PER ROW */
  grid-gap: 10px;
  max-width: 1200px;
  margin: 0 auto; /* HORIZONTAL CENTER */
}
.gallery img {
  width: 100%;
  height: 200px;
  /* FILL, CONTAIN, COVER, SCALE-DOWN : USE WHICHEVER YOU LIKE */
  object-fit: cover;
}

/* (B) RESPONSIVE - MOBILE FRIENDLY */
@media screen and (max-width: 640px) {
  .gallery {
    grid-template-columns: repeat(2, auto); /* 2 ITEMS PER ROW */
  }
}

/* (X) DOES NOT MATTER */
body, html {
  padding: 0;
  margin: 0;
}

Of course, we are not so “barbaric” to just row out raw images without any cosmetics. So here is how we use a simple CSS grid to make it look like a legit gallery, also add some responsive mobile-friendly magic. Please feel free to modify these to fit your own project.

 

STEP 2

ADDING A LIGHTBOX

Actually, we already have a gallery. So this is kind of an extra step for those of you who want to show the full-sized image when the user clicks on a gallery item.

 

THE (SLIGHTLY IMPROVED) PHP & HTML

2-box.php
<!DOCTYPE html>
<html>
  <head>
    <title>Simple PHP gallery</title>
 
    <!-- (A) CSS + JS -->
    <link href="1-basic.css" rel="stylesheet">
    <link href="2-box.css" rel="stylesheet">
    <script src="2-box.js"></script>
  </head>
  <body>
    <!-- (B) LIGHTBOX -->
    <div id="lback">
      <div id="lfront"></div>
    </div>

    <!-- (C) THE GALLERY -->
    <div class="gallery"><?php
    // (C1) READ FILES FROM GALLERY FOLDER
    $dir = __DIR__ . DIRECTORY_SEPARATOR . "gallery" . DIRECTORY_SEPARATOR;
    $images = glob($dir . "*.{jpg,jpeg,gif,png,bmp,webp}", GLOB_BRACE);
 
    // (C2) OUTPUT IMAGES 
    foreach ($images as $i) {
      printf("<img src='gallery/%s' onclick='gallery.show(this)'/>", basename($i));
    }
    ?></div>
  </body>
</html>

Not much of a difference here, except:

  • Additional Javascript to control the full-sized image popup.
  • Two new <div> for the image popup –
    • <div id="lback"> is a full-page sized solid color background.
    • <div id="lfront"> to put the selected image into.
  • Added “click to show full size” on the images in the gallery.

 

 

THE CSS

2-box.css
/* (A) SMALL GALLERY ADD-ON */
.gallery img:hover {
  cursor: pointer;
}
 
/* (B) LIGHTBOX BACKGROUND */
#lback {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 999;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  visibility: hidden;
  transition: all ease 0.5s;
}
#lback.show {
  opacity: 1;
  visibility: visible;
}

/* (C) LIGHTBOX IMAGE */
#lfront {
  text-align: center;
  position: relative;
  top: 50vh;
  transform: translateY(-50%);
}
#lfront img {
  max-width: 80vw;
  max-height: 80vh;
}

Basically, we just added a new lightbox section to the CSS – We will be playing with the .show CSS class to show/hide the popup.

 

 

THE JAVASCRIPT

2-box.js
var gallery = {
  // (A) SHOW SELECTED IMAGE IN LIGHT BOX
  show : function(img){
    var clone = img.cloneNode(),
        front = document.getElementById("lfront"),
        back = document.getElementById("lback");
 
    front.innerHTML = "";
    front.appendChild(clone);
    back.classList.add("show");
  },
 
  // (B) HIDE THE LIGHTBOX
  hide : function(){
    document.getElementById("lback").classList.remove("show");
  }
};

Only 2 functions in this script:

  • Show: fired when the user clicks on an image. Duplicates the selected image, puts it into the lightbox, then show the full-sized image by adding the .show CSS class.
  • Hide: Closes the full-sized image popup. Simply removes the .show CSS class.

 

EXTRA

USEFUL BITS & LINKS

That’s it for all the code. Here are some extras that may be useful to you.

 

AUTO THUMBNAILS GENERATOR

As simple as this gallery might be – You have to remember that it is loading whatever full-sized images that you put inside the gallery folder… That is not good if you are trying to create a “fast loading website”. So here is one last extra that will automatically generate thumbnails.

3-thumbnail.php
<!DOCTYPE html>
<html>
  <head>
    <title>Simple PHP gallery</title>
 
    <!-- (A) CSS + JS -->
    <link href="1-basic.css" rel="stylesheet">
    <link href="2-box.css" rel="stylesheet">
    <script src="3-thumbnail.js"></script>
  </head>
  <body>
    <!-- (B) LIGHTBOX -->
    <div id="lback" onclick="gallery.hide()">
      <div id="lfront"></div>
    </div>
 
   <!-- (C) THE GALLERY -->
   <div class="gallery"><?php
   // (C1) INIT
   $dir = __DIR__ . DIRECTORY_SEPARATOR . "gallery" . DIRECTORY_SEPARATOR;
   $tdir = __DIR__ . DIRECTORY_SEPARATOR . "thumbnail" . DIRECTORY_SEPARATOR;
   $maxLong = 600; // maximum width or height, whichever is longer
   $images = [];
 
   // (C2) READ FILES FROM GALLERY FOLDER
   $files = glob($dir . "*.{jpg,jpeg,gif,png,bmp,webp}", GLOB_BRACE);
 
   // (C3) CHECK AND GENERATE THUMBNAILS
   foreach ($files as $f) {
     $img = basename($f);
     $images[] = $img;
     if (!file_exists($tdir . $img)) {
       // EXTRACT IMAGE INFORMATION
       $ext = strtolower(pathinfo($img)['extension']);
       list ($width, $height) = getimagesize($dir . $img);
       $ratio = $width > $height ? $maxLong / $width : $maxLong / $height ;
       $newWidth = ceil($width * $ratio);
       $newHeight = ceil($height * $ratio);
 
       // RESIZE
       $fnCreate = "imagecreatefrom" . ($ext=="jpg" ? "jpeg" : $ext);
       $fnOutput = "image" . ($ext=="jpg" ? "jpeg" : $ext);
       $source = $fnCreate($dir . $img);
       $destination = imagecreatetruecolor($newWidth, $newHeight);
 
       // TRANSPARENT IMAGES ONLY
       if ($ext=="png" || $ext=="gif") {
         imagealphablending($destination, false);
         imagesavealpha($destination, true);
         imagefilledrectangle(
         $destination, 0, 0, $newWidth, $newHeight,
         imagecolorallocatealpha($destination, 255, 255, 255, 127)
       );
     }
 
      // SAVE RESIZED IMAGE
      imagecopyresampled($destination, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
      $fnOutput($destination, $tdir . $img);
    }
  }
 
  // (C4) OUTPUT IMAGES
  foreach ($images as $i) {
    printf("<img src='thumbnail/%s' onclick='gallery.show(this)'/>", basename($i));
  }
  ?></div>
  </body>
</html>

Finally, all we need to do is to modify the show function a little to show the full-resolution image on click:

3-thumbnail.js
var gallery = {
  // (A) SHOW SELECTED IMAGE IN LIGHT BOX
  show : function(img){
    var clone = img.cloneNode(),
        domain = clone.src.substr(0, clone.src.lastIndexOf("/",clone.src.lastIndexOf("/")-1)+1),
        image = clone.src.substr(clone.src.lastIndexOf("/")+1),
        front = document.getElementById("lfront"),
        back = document.getElementById("lback");

    clone.src = domain + "gallery/" + image;
    clone.onclick = "";
    front.innerHTML = "";
    front.appendChild(clone);
    back.classList.add("show");
  },

  // (B) HIDE THE LIGHTBOX
  hide : function(){
    document.getElementById("lback").classList.remove("show");
  }
};

 

 

FILENAME AS IMAGE TITLE

Since there is no database, there is also no way to we can include captions. But we can still use the file name as the title of the image, just modify the PHP a little bit to also output the title.

foreach ($images as $i) {
  printf("<img src='gallery/%s' title='%s'/>", basename($i), basename($i));
}

 

FILE SORT

Need to sort the files by the file timestamp? Use the usort() method after getting the list of image files.

// $images = glob(...);

usort(
  $images,
  function($file1, $file2) {
    return filemtime($file2) <=> filemtime($file1); // Newest file first
    // Oldest file first
    // return filemtime($file1) <=> filemtime($file2);
  }
);

Or to sort in the alpha-numeric order:

sort($images); // Low to high
rsort($images); // High to low

 

READING MULTIPLE FOLDERS

The glob() function simply returns an array of image files, so we can combine it with the use of array_merge() when required.

$images = array_merge(
  $images, 
  glob(ANOTHER-FOLDER . "*.{jpg,jpeg,gif,png,bmp,webp}", GLOB_BRACE)
);

But of course, this is good only as a “quick fix”… Not recommended if you have a dozen folders.

 

MULTIPLE FOLDERS & CATEGORIES

If you have multiple folders, each for a different category, simply repeat the “get an array of image files, output in HTML”.

<div class="gallery"><?php
$images = glob(FOOD GALLERY FOLDER);
foreach ($images as $i) {printf("<img ... />"); }
?></div>
 
<div class="gallery"><?php
$images = glob(FOOD GALLERY FOLDER);
foreach ($images as $i) {printf("<img ... />"); }
?></div>

 

SUPPORTING VIDEOS

It is possible to do so… But it does require quite a bit of extra work. First, simply add video extensions into glob().

$images = glob($dir . "*.{jpg,jpeg,gif,png,bmp,webp,avi,mp4}", GLOB_BRACE);

Then, modify the HTML output to check if image or video.

foreach ($images 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));
  }
}

Finally, 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.

 

USEFUL LINKS

 

EXTRA

VIDEO TUTORIAL

For you guys who want more, here’s the video tutorial, and shameless self-promotion – Subscribe to the Code Boxx YouTube channel for more!

 

YOUTUBE TUTORIAL

 

THE CHEAT SHEET

Simple No Database Gallery With PHP (Click to Enlarge)

 

CLOSING

WHAT’S NEXT?

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!

33 thoughts on “2 Steps Very Simple PHP Gallery (From Folder No Database)”

  1. HI,
    This is a great tutorial. Works wonderfully for my image gallery. But can you help me add a close button and left/right arrows once the image is opened in full size in the lightbox?
    Thanks

  2. This tutorial is amazing! Thank you for this.

    I’ve been playing with the code and I’m wondering how I could have multiple instances of this PHP code on the same page showing galleries from different folders as separate elements. Is that possible?

    1. Jean-Marie Larchevêque

      If you find that { object-fit: cover; } changes the aspect ratio of narrow portrait photos (as I found it did for me, though I understand it’s not supposed to), you can use { object-fit: contain; } instead.

  3. Great and detailed tutorial! Very impressed with how fast you reply to questions! 🙂

    I have two questions that I cannot find in the answer for in the guide or in the previous comments.
    1. How could I create an area with text below or above the lightbox image? For example a button to open image in new tab, or show the image title/name?
    2. I understand I can upload from multiple folders. I would love to have a sorting option by image tags. For example sort by car-images or sort by fruit-images. Is there a way to set a tag to each image?

    Thank you very much in advance!

    1. Just add a <div> into the lightbox? <div id="lfront"><div id="lbcaption"></div></div>.
      But given all your requirements – There is no database to store captions, tags, titles, nor are there additional data that can be used for “custom sorting”. I will highly recommend you look for a “full-featured gallery”, or building on top of this is going to be a long painful process…

    1. glob(FOLDER . "*.{FILE EXTENSION}", GLOB_BRACE) simply returns an array of files, so –

      * Just add the video files (.mp4, .webm, .avi) to the list of file extensions.
      * Just use $images = array_merge($images, glob(FOLDER 2, ...)) for more folders.
      * In the for loop, check for video files (hint: file_info() function), and generate <video> tags instead of image.
      * Update the CSS and Javascript to also support video.

  4. hi great tutorial, thanks, would it be possible to have all the images in one row with left and right scroll buttons, similar to a carousel?
    thanks very much !

  5. Great PHP Gallery, easy and simple. Thank you so much for the tutorial!. I have problems with PNG files with transparent background. The thumbnails created are all black. Is there a way to add background, for example in white? When i try to open the thumbnails in file explorer, it tells me that the files are corrupt….
    Thank you again!

      1. Yeah! That was great! I changed de CSS to avoid pixeling small images:
        #gallery img {
        box-sizing: border-box;
        width: 25%;
        max-height: 150px;
        padding: 5px;
        /* fill, contain, cover, scale-down : use whichever you like */
        object-fit: contain; <– changed from cover.
        cursor: pointer;
        }
        Now i'll try to make all directory recursive.
        Tank you so much!

  6. Is the gallery great, a query, how could it be modified so that the latest added photos are the first to be seen? Thank you.

      1. Hi, great tutorial for lightweight solution!
        I have a hard time applying this properly to your tutorial. How and where would you add this?
        Also is there a possibility to add left and right buttons to cycle through the images once you open them to the lightbox?
        Newbie asking. Thanks! 🙂

        1. Yes, of course, it is possible to add left/right on top of this one – But if you are having trouble understanding this “barebones gallery”, I will highly suggest you start with the basics and understand what is going on first… P.S. Read the entire tutorial, the answer is literally right above in the extras section.

  7. thank you for this solution.
    i could use some help with two issues:
    1) what is needed to be able to replace the “gallery” folder with /full/path/to/some/other/folder? i tried this and my gallery remained white
    2) when i click images that are too big for the screen, they do get opened full size and it is not possible to use scrollbar, middle click, etc. how to i tell php/js to just scale correctly?

    best
    benedikt

      1. Thanks W.S. Toh for your very nice gallery code, it helped me a lot.
        I had the same issue as benedikt and i made light changes that fully address the needs in responsive mode:
        I modified only 2 lines in the “file 2-box.css”:

        #lfront img {
        max-width: auto;
        max-height: 100vh; <=== this first line modified
        margin: 0 auto;
        display: block;
        }
        #lback {
        height: 100vh; <=== this second line modified
        background: #000;

        Best regards. johann

  8. Great Job!!!!
    its posible to add buttons under the image popup to share on Instagram, Facebook and tweeter???

  9. Super easy and simple. Thank you!

    One thing someone else may run into:

    My camera by default would make the file name and extension all in uppercase. So the script behaved like the gallery folder was empty until I changed all the photos from .JPG to .jpg

    1. Just add Uppercase JPG to the selection … faster

      $files = glob($dir . “*.{JPG,jpg,jpeg,gif,png}”, GLOB_BRACE);

Leave a Comment

Your email address will not be published. Required fields are marked *