Простая фотогалерея на базе данных MySQL может быть создана на популярном языке программирования PHP. Пример алгоритма, который можно использовать для создания простой фотогалереи: создайте базу данных в MySQL, создайте таблицу для хранения изображений, напишите функцию для загрузки изображений, создайте форму для загрузки изображений и обработчик для сохранения изображений в базе данных, напишите обработчик, который загрузит изображения в базу.
Реализация с системой управления базой данных MySQL.
Работа с базой данных
Статья посвящена решению задачи из десятого урока книги Д. Ляпина, А. Никитина «PHP – это просто». В этом уроке Дмитрий Ляпин и Александр Никитин объясняют, как работать с базой данных (БД). Коротко, что такое БД я написал в PHP с базой данных MySQL. Работа с базой данных показана на примере реализации фотогалереи. Использованы результаты работы из урока 9.
Задание по доработке фотогалереи
Задание:
Доработать галерею фотографий с использованием базы данных.
Возможности:
демонстрация количества просмотров фотографии полного размера;
на странице галереи всех изображений сделать список фотографий и отсортировать их по популярности (количеству просмотров) ;
самые популярные (с наибольшим количеством кликов уменьшенного фото для просмотра полного изображения) - в начале списка.
Подсказки:
во время загрузки фото выделить уникальный идентификатор;
идентификатор и тип изображения ('jpg', 'jpeg', 'png', 'gif') хранить в БД;
изображения уменьшенного размера хранить в отдельной папке и дать им имена вида "идентификатор.тип";
так же поступить с изображениями полного размера.
Решение:
Для решения этой задачи, то есть создания сайта фотогалереи с использованием БД, воспользуемся готовым решением задания предыдущего урока. Но придется внести некоторые изменения в файлы сайта, создать базу данных lyapin c таблицами big и small. Каталоги останутся прежние: img_big - для больших фото и img_small - для уменьшенных картинок.
Файл главной страницы index.php:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Галерея фото</title>
</head>
<body>
<h1>Галерея фотографий</h1>
<section style="width: 14%; float: left">
<h4>Популярные фото<
/h4>
<?php
require_once ('function.php');
getList ();
?>
</section>
<section>
<?php
//вывод картинок
$dir = "img_small"; // Путь к директории, в которой лежат малые изображения
$files = scandir($dir); // Получаем список файлов из этой директории
$files = excess($files); // Удаляем лишние файлы c '.' ...
/* Дальше происходит вывод картинок на страницу сайта */
for ($i = 0; $i < count($files); $i++)
{
?>
<!-- Делаем ссылку на страницу с большой картинкой, вывод малых картинок -->
<a href="clicks.php?id=<?=$files[$i]?>"><img src="<?=$dir . "/" . $files[$i]?>" alt="Фото галереи" /></a>
<?php
}
?>
<h2>Загрузить фотографию</h2>
<form action="upload.php" method="post" enctype="multipart/form-data">
<p><input type="file" name="file"></p>
<p><input type="submit" name="load" value="Загрузить файл"></p>
<br>
</form>
</section>
</body>
</html>
Библиотека функций фотогалереи function.php:
<?php
/*
* Функция загрузки файла (аплоадер)
$max_file_size максимальный размер файла в мегабайтах
$valid_extensions массив допустимых расширений
string $upload_dir директория загрузки
* @return [] сообщение о ходе выполнения
*/
/* В php скрипте реализованы две проверки:
так как хостер ограничивает размер загружаемого файла (на момент написания данного материала у меня на хостинге стоит ограничение в 8 Mb), то проверка максимального размера необходима;
проверка расширения файла позволяет отсеять ненужные файлы до загрузки.
URL фотографии - $destination. return $destination А далее вставляете URL фото куда вам надо */
function upload($max_file_size, $valid_extensions, $upload_dir)
{
setlocale(LC_ALL, 'ru_RU . UTF8');
$error = null;
$info = null;
$max_file_size *= 1048576; // перевод размера файла в b
if ($_FILES['file']['error'] === UPLOAD_ERR_OK)
{
// проверяем расширение файла
$file_extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
if (in_array(strtolower($file_extension), $valid_extensions))
{
// проверяем размер файла
if ($_FILES['file']['size'] < $max_file_size)
{
$file = $_FILES["file"]["tmp_name"];
$myfile_name = $_FILES["file"]["name"];
$file_type = substr($myfile_name, strrpos($myfile_name, '.')+1); //strrpos - Возвращает позицию последнего вхождения символа
$file_name = assignName('big', $file, $file_type); //
$destination = $upload_dir .'/' . $file_name;
if (move_uploaded_file($_FILES['file']['tmp_name'], $destination))//Перемещает загруженный файл в новое место.
{
$info = 'Файл успешно загружен';
}
else
$error = 'Не удалось загрузить файл';
}
else
$error = 'Размер файла больше допустимого';
}
else
$error = 'У файла недопустимое расширение';
}
else
{
// массив ошибок
$error_values = [
UPLOAD_ERR_INI_SIZE => 'Размер файла больше разрешенного директивой upload_max_filesize в php.ini',
UPLOAD_ERR_FORM_SIZE => 'Размер файла превышает указанное значение в MAX_FILE_SIZE',
UPLOAD_ERR_PARTIAL => 'Файл был загружен только частично',
UPLOAD_ERR_NO_FILE => 'Не был выбран файл для загрузки',
UPLOAD_ERR_NO_TMP_DIR => 'Не найдена папка для временных файлов',
UPLOAD_ERR_CANT_WRITE => 'Ошибка записи файла на диск'
];
$error_code = $_FILES['file']['error'];
if (!empty($error_values[$error_code]))
$error = $error_values[$error_code];
else
$error = 'Случилось что-то непонятное';
}
return ['info' => $info, 'error' => $error, 'destination'=>$destination];
}
/*
Функция уменьшения размера фотографии.
Параметры:
$src - имя исходного файла
$dest - имя генерируемого файла
$width, $height - ширина и высота генерируемого изображения, в пикселях
Необязательные параметры:
$rgb - цвет фона, по умолчанию - белый
$quality - качество генерируемого JPEG, по умолчанию - максимальное (100)
*/
function img_resize($src, $dest, $width, $height, $rgb = 0xFFFFFF, $quality = 100)
{
if (!file_exists($src)) // Проверить наличие указанного файла или каталога.
return false;
$size = getimagesize($src);
if ($size === false)
return false;
$format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1));
$icfunc = 'imagecreatefrom' . $format;
if (!function_exists($icfunc))
return false;
$x_ratio = $width / $size[0];
$y_ratio = $height / $size[1];
if ($height == 0)
{
$y_ratio = $x_ratio;
$height = $y_ratio * $size[1];
}
elseif ($width == 0)
{
$x_ratio = $y_ratio;
$width = $x_ratio * $size[0];
}
$ratio = min($x_ratio, $y_ratio);
$use_x_ratio = ($x_ratio == $ratio);
$new_width = $use_x_ratio ? $width : floor($size[0] * $ratio);
$new_height = !$use_x_ratio ? $height : floor($size[1] * $ratio);
$new_left = $use_x_ratio ? 0 : floor(($width - $new_width) / 2);
$new_top = !$use_x_ratio ? 0 : floor(($height - $new_height) / 2);
// если не нужно увеличивать маленькую картинку до указанного размера
if ($size[0]<$new_width && $size[1]<$new_height)
{
$width = $new_width = $size[0];
$height = $new_height = $size[1];
}
$isrc = $icfunc($src);
$idest = imagecreatetruecolor($width, $height);
imagefill($idest, 0, 0, $rgb);
imagecopyresampled($idest, $isrc, $new_left, $new_top, 0, 0, $new_width, $new_height, $size[0], $size[1]);
$i = strrpos($dest,'.');
if (!$i) return '';
$l = strlen($dest) - $i;
$ext = substr($dest,$i+1,$l);
switch ($ext)
{
case 'jpeg':
case 'jpg':
imagejpeg($idest,$dest,$quality);
break;
case 'gif':
imagegif($idest,$dest);
break;
case 'png':
imagepng($idest,$dest);
break;
}
imagedestroy($isrc);
imagedestroy($idest);
return true;
}
/* Функция для удаления лишних файлов: Текущий каталог и родительский пропускаем, не выводим файлы Thumbs.db */
function excess($files)
{
$result = [];
for ($i = 0; $i < count($files); $i++)
{
if ($files[$i] != "." && $files[$i] != ".." && $files[$i] != "Thumbs.db")
$result[] = $files[$i];
}
return $result;
}
// Подключение к БД lyapin
function connect()
{
$link = mysqli_connect('127.0.0.1', 'root', '', 'lyapin'); // Открывает новое соединение с сервером MySQL и БД .
if (!$link)
{
die('Ошибка подключения (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}
return $link;
}
//Добавить запись в БД и назначить имя файлу
function add($table_name, $file_type, $file, $myfile_name)
{
/* соединение с базой данных */
$link = connect();
$file_type = mysqli_real_escape_string($link, $file_type);
//Добавление записи в базу данных тип файла и временное имя файла на нашем сервере (во время запроса)
$sql = "INSERT INTO $table_name (typ, thum_des, myfile_name) VALUES ('$file_type', '$file', '$myfile_name')";
mysqli_query($link, $sql);//запрос к базе данных на добавление записи
//Выборка в таблице id, соответсвующего предыдущей добавленной записи
$id_find = "SELECT id FROM $table_name WHERE thum_des = '$file'";
$result = mysqli_query($link, $id_find);//запрос к БД
$row = mysqli_fetch_row($result);
//Определение значения из массива
$row = $row[0];
/* Назначение имени файлу вида "идентификатор.тип" */
$designation = ($row . '.' . $file_type);
/* Изменение значения поля designation в таблице на значение вида "идентификатор.тип" */
$sql = "UPDATE $table_name SET designation='$designation' WHERE id=$row";
mysqli_query($link, $sql);
/* закрываем соединение */
mysqli_close($link);
}
//Добавить запись в базу данных в таблицу small
function addSmall($file_type, $file_name)
{
/* соединение с базой данных */
$link = connect();
$address = ('img_small/' . $file_name);
$file_type = mysqli_real_escape_string($link, $file_type);
$file_name = mysqli_real_escape_string($link, $file_name);
//Добавление записи в базу данных тип файла и временное имя файла на нашем сервере (во время запроса)
$sql = "INSERT INTO small (typ, designation, address) VALUES ('$file_type', '$file_name', '$address')";
mysqli_query($link, $sql);//запрос к БД на добавление записи
/* закрываем соединение */
mysqli_close($link);
}
/* Назначение имени файлу вида "идентификатор.тип" */
function assignName($table_name, $file, $file_type)
{
/* соединение с БД */
$link = connect();
//Выборка в таблице id, соответсвующего предыдущей добавленной записи
$id_find = "SELECT id FROM $table_name WHERE thum_des = '$file'";
$result = mysqli_query($link, $id_find);//запрос к базе данных
$row = mysqli_fetch_row($result);
//Определение значения из массива
$row = $row[0];
/* Назначение имени файлу вида "идентификатор.тип" */
$designation = ($row . '.' . $file_type);
/* очищаем результирующий набор */
mysqli_free_result($result);
/* закрываем соединение */
mysqli_close($link);
return $designation;
}
//количество кликов по определенному url.
function click($table_name, $id)
{
/* соединение с базой данных */
$link = connect();
/*Увеличиваем количество кликов по определенному url. При этом id указывает на нужную запись.*/
$update = "UPDATE $table_name SET click = click + 1, designation = designation, thum_des = thum_des, typ = typ WHERE designation='$id'";
/*Все значения кроме id в этом запросе переназначаются. Таким образом, не нужно вставлять новый id, для нового url.*/
mysqli_query($link, $update);
//Теперь достаем url и делаем туда редирект
$query = "SELECT * FROM $table_name WHERE designation='$id'";
$result = mysqli_query($link, $query);
$tab = mysqli_fetch_array($result);
$url = $tab["url"];
/* очищаем результирующий набор */
mysqli_free_result($result);
/* закрываем соединение */
mysqli_close($link);
header("location: $url");
}
/*Получить количество просмотров фотографии*/
function getClicks($id)
{
/* соединение с базой данных */
$link = connect();
//Выборка в таблице address
$id_find = "SELECT click FROM big WHERE designation='$id'";
$result = mysqli_query($link, $id_find);//запрос к БД
$row = mysqli_fetch_array($result);
$row = $row[0];
/* очищаем результирующий набор */
mysqli_free_result($result);
/* закрываем соединение */
mysqli_close($link);
return $row;
}
/*Получить список фото*/
function getList ()
{
/* соединение с базой данных */
$link = connect();
//Выборка в таблице big
$id_find = "SELECT designation, myfile_name FROM big ORDER BY click DESC ";
$result = mysqli_query($link, $id_find);//запрос к БД
/* выборка данных и помещение их в массив */
while ($row = mysqli_fetch_row($result))
{
printf ("%s (%s)<br>", $row[0], $row[1]);
}
}
Файл-обработчик upload.php:
<?php
/*файл–обработчик формы загрузки пользовательского файла.*/
include("function.php"); // подключаем файл с функциями
// Запускаем функцию загрузки
if(!empty($_POST['load'])) // если кнопка "Загрузить файл" нажата
{
ini_set('max_file_uploads', '3'); /*Установить максимальное количество загружаемых на сервер файлов за один раз*/
$valid_extensions = ['jpg', 'jpeg', 'png', 'gif'];
$upload_dir = 'img_big'; // папка для загрузки (создать на сервере)
$file = $_FILES["file"]["tmp_name"];
$myfile_name = $_FILES["file"]["name"];
$file_type = substr($myfile_name, strrpos($myfile_name, '.') + 1); //strrpos - Возвращает позицию последнего вхождения символа
// Если загрузка файла на сервер успешная
if(isset($_FILES["file"]))//Определяет, была ли установлена переменная значением отличным от NULL
{
$file_size = $_FILES["file"]["size"];
$error_flag = $_FILES["file"]["error"];
// Если ошибок не было
if($error_flag == 0)
{
$f_thum = "big/thum_" . $myfile_name;
/*добавление записи в таблицу БД*/
add('big', $file_type, $file, $myfile_name);
//print("<br>" . "Имя файла на нашем сервере (во время запроса): " . $file . "<br>");
print("<br>" . "Имя файла на компьютере пользователя: " . $myfile_name . "<br>");
print("Размер файла: " . $file_size . ' bytes' . "<br>");
}
}
$message = upload(1, $valid_extensions, $upload_dir);
// Выводим сообщение
echo $message['error'] ? $message['error'] : $message['info'];
echo '<br /><br />';
echo '<a href="index.php">Вернуться на страницу галереи</a>';
$src = $message['destination'];
/* чтобы изменить размеры фото необходимо запустить функцию img_resize с нужными параметрами ширины и высоты нового изображения. Если нужен только один параметр, например ширина 200px, то высоту задаем равную 0 (ноль). При этом получим пропорциональное фото с шириной 200px.*/
$file_name = assignName('big', $file, $file_type);
$dest = 'img_small/' . $file_name;
img_resize($src, $dest, 200, 0);
//Добавить запись в базу данных в таблицу small
addSmall($file_type, $file_name);
}
?>
Для представления фотографии полного размера и демонстрации количества кликов по фото создадим файл clicks.php:
<?php
require_once ('function.php');
$dir_big = "img_big"; // Путь к директории, в которой лежат большие изображения
click('big', $_GET['id']);//Подсчитываем количество просмотров
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Крупно</title>
</head>
<body>
<figure>
<img src="<?=$dir_big . "/" . $_GET['id']?>" alt="Фото <?=$_GET['id']?>">
<figcaption>Количество просмотров: <strong><?=getClicks($_GET['id'])?></strong></figcaption>
</figure>
<a href="index.php">Вернуться на страницу галереи</a>
</body>
</html>
Отображение функционала фотогалереи
Посмотреть работу сайта с галереей фотографий в новом окне. На практике можно загрузить изображение, посмотреть его в увеличенном формате, узнать количество просмотров. Чистый функционал без дизайна.