A fully functional image gallery with upload capabilities using PHP, HTML, jQuery, AJAX, JSON, Bootstrap, CSS, and MySQL. This project includes a detailed step-by-step solution with code explanations and documentation, making it a comprehensive tutorial for learning.
Topics: php
, mysql
, blog
, ajax
, bootstrap
, jquery
, css
, image gallery
, file upload
Step-by-Step Solution
1. Directory Structure
simple-image-gallery/
│
├── index.html
├── db/
│ └── database.sql
├── src/
│ ├── fetch-image.php
│ └── upload.php
├── include/
│ ├── config.sample.php
│ └── db.php
├── assets/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── uploads/
│ │ └── (uploaded images will be stored here)
├── README.md
└── .gitignore
2. Database Schema
db/database.sql:
CREATE TABLE IF NOT EXISTS `images` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`file_name` varchar(255) NOT NULL,
`uploaded_on` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3. Configuration File
Configuration settings (include/config.sample.php)
<?php
define('DB_HOST', 'localhost'); // Database host
define('DB_NAME', 'image_gallery'); // Database name
define('DB_USER', 'root'); // Change if necessary
define('DB_PASS', ''); // Change if necessary
define('UPLOAD_DIRECTORY', '/assets/uploads/'); // Change if necessary
?>
4. Configure the Database Connection
Establishing database connection (include/db.php)
<?php
include 'config.php';
// Database configuration
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME;
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
// Create a new PDO instance
try {
$pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set error mode to exception
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage(); // Display error message if connection fails
}
?>
5. HTML and PHP Structure
HTML Structure (index.html
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Gallery Upload</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body>
<div class="container">
<h1 class="text-center mt-5">Image Gallery</h1>
<div class="row">
<div class="col-md-6 offset-md-3">
<form id="uploadImage" enctype="multipart/form-data">
<div class="form-group">
<label for="image">Choose Image</label>
<input type="file" name="image" id="image" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
<div id="upload-status"></div>
</div>
</div>
<hr>
<div class="row" id="gallery">
<!-- Images will be loaded here -->
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="assets/js/script.js"></script> <!-- Custom JS -->
</body>
</html>
6. JavaScript and AJAX
AJAX Handling (assets/js/script.js
)
$(document).ready(function(){
// load gallery on page load
loadGallery();
// Form submission for image upload
$('#uploadImage').on('submit', function(e){
e.preventDefault(); // Prevent default form submission
var file_data = $('#image').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
//hide upload section
$('#uploadImage').hide();
$.ajax({
url: 'src/upload.php', // PHP script to process upload
type: 'POST',
dataType: 'text', // what to expect back from the server
cache: false,
data: new FormData(this), // Form data for upload
processData: false,
contentType: false,
success: function(response){
let jsonData = JSON.parse(response);
if(jsonData.status == 1){
$('#image').val(''); // Clear the file input
loadGallery(); // Fetch and display updated images
$('#upload-status').html('<div class="alert alert-success">'+jsonData.message+'</div>');
} else {
$('#upload-status').html('<div class="alert alert-success">'+jsonData.message+'</div>'); // Display error message
}
// hide message box
autoHide('#upload-status');
//show upload section
autoShow('#uploadImage');
}
});
});
});
// Function to load the gallery from server
function loadGallery() {
$.ajax({
url: 'src/fetch-images.php', // PHP script to fetch images
type: 'GET',
success: function(response){
let jsonData = JSON.parse(response);
$('#gallery').html(''); // Clear previous images
if(jsonData.status == 1){
$.each(jsonData.data, function(index, image){
$('#gallery').append('<div class="col-md-3"><img src="assets/uploads/'+image.file_name+'" class="img-responsive img-thumbnail"></div>'); // Display each image
});
} else {
$('#gallery').html('<p>No images found...</p>'); // No images found message
}
}
});
}
//Auto Hide Div
function autoHide(idORClass) {
setTimeout(function () {
$(idORClass).fadeOut('fast');
}, 1000);
}
//Auto Show Element
function autoShow(idORClass) {
setTimeout(function () {
$(idORClass).fadeIn('fast');
}, 1000);
}
7. Backend PHP Scripts
Fetching Images (src/fetch-images.php
)
<?php
include '../include/db.php'; // Include database configuration
$response = array('status' => 0, 'message' => 'No images found.');
// Fetching images from the database
$query = $pdo->prepare("SELECT * FROM images ORDER BY uploaded_on DESC");
$query->execute();
$images = $query->fetchAll(PDO::FETCH_ASSOC);
if(count($images) > 0){
$response['status'] = 1;
$response['data'] = $images; // Returning images data
}
// Return response
echo json_encode($response);
?>
?>
Image Upload (src/upload.php
)
<?php
include '../include/db.php'; // Include database configuration
$response = array('status' => 0, 'message' => 'Form submission failed, please try again.');
if(isset($_FILES['image']['name'])){
// Directory where files will be uploaded
$targetDir = UPLOAD_DIRECTORY;
$fileName = date('Ymd').'-'.str_replace(' ', '-', basename($_FILES['image']['name']));
$targetFilePath = $targetDir . $fileName;
$fileType = pathinfo($targetFilePath, PATHINFO_EXTENSION);
// Allowed file types
$allowTypes = array('jpg','png','jpeg','gif');
if(in_array($fileType, $allowTypes)){
// Upload file to server
if(move_uploaded_file($_FILES['image']['tmp_name'], $targetFilePath)){
// Insert file name into database
$insert = $pdo->prepare("INSERT INTO images (file_name, uploaded_on) VALUES (:file_name, NOW())");
$insert->bindParam(':file_name', $fileName);
$insert->execute();
if($insert){
$response['status'] = 1;
$response['message'] = 'Image uploaded successfully!';
}else{
$response['message'] = 'Image upload failed, please try again.';
}
}else{
$response['message'] = 'Sorry, there was an error uploading your file.';
}
}else{
$response['message'] = 'Sorry, only JPG, JPEG, PNG, & GIF files are allowed to upload.';
}
}
// Return response
echo json_encode($response);
?>
6. CSS Styling
CSS Styling (assets/css/style.css
)
body {
background-color: #f8f9fa;
}
#gallery .col-md-4 {
margin-bottom: 20px;
}
#gallery img {
display: block;
width: 200px;
height: auto;
margin: 10px;
}
Documentation and Comments
-
config.php
: Contains database configuration and connects to MySQL using PDO. -
index.php
: Main page with HTML structure, includes Bootstrap for styling, and a modal for adding/editing posts. -
assets/js/script.js
: Handles AJAX requests for loading and saving posts. Uses jQuery for DOM manipulation and AJAX. -
src/fetch-images.php
: Fetches posts from the database and returns them as JSON. -
src/upload.php
: Handles post creation and updating based on the presence of an ID.
This solution includes setting up the project, database configuration, HTML structure, styling with CSS, handling image upload with AJAX, and storing image data in the database using PHP PDO. Each line of code is commented to explain its purpose and functionality, making it a comprehensive tutorial for building an image gallery with upload functionality.
Connecting Links
If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!
If you want more helpful content like this, feel free to follow me: