PHP: галерея
создаем простую галерею картинок с помощью PHP

Реализуем простую, но полнофункциональную галерею с возможностью загрузки собственных файлов изображений с помощью PHP, HTML, jQuery, AJAX, JSON, Bootstrap, CSS, и MySQL.
Структура проекта
simple-image-gallery/
│
├── index.php
├── 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
Создаем базу данных
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;
Обновляем реквизиты базы данных
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
Настраиваем подключение к базе данных через PDO
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
}
Создаем структуру HTML
index.php
<!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>
JavaScript и AJAX
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);
}
PHP скрипты
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);
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);
Создаём стили CSS
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;
}
Объяснение
- config.sample.php: конфигурация базы данных и подключение к ней через PDO.
- index.php: HTML разметка страницы, включающая классы Bootstrap.
- assets/js/script.js: Обработка AJAX-запроса для загрузки и сохранения изображений. Для взаимодействия с AJAX и динамического построения DOM используется jQuery.
- src/fetch-images.php: извлечение информации об изображениях из базы данных и её упаковка в JSON.
- src/upload.php: создание записи в базе данных с присвоением ID и реализация возможности её изменения.
Спасибо за внимание.
Перевод статьи MD ARIFUL HAQUE “PHP crash course: Simple Image Gallery”