-
Урок 13.Создание фотогалереи на сайте. Менеджер изображений.
Август 21st, 2008 81 КомментариевПожалуй даже самый ленивый программист не задавался вопросом создания фотогалереи на сайте. Сейчас в сети достаточно много разнообразных сервисов для хранения своих фотографий, но что если хочеться создать персональную фотогалерею, которая должна отображаться на вашем сайте? Попробуем решить данную проблему в этом уроке.
Детали
В данном уроке предлагаю рассмотреть два базовых принципа:
- Обычный листинг изображений из директории на сервере;
- Менеджер изображений с использованием БД MySQL, состоящий из административной и пользовательской части, позволяющий загружать/удалять изображения, составлять описания к ним и тд.
Простая фотогалерея
Для создания простой галереи больших знаний не требуется. Чтобы выводить изображения на страницу, нам потребуется функции для работы с файлами и папками. Для удобства мы оборудуем этот пример постраничной навигацией.
index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<?php
//Папка с изображениями
$url="gallery";
//Количество на странице
$max=5;
//Проверяем, является ли директорией
if (is_dir($url)) {
//Проверяем, была ли открыта директория
if ($dir = opendir($url)) {
//Сканируем директорию
while ($file = readdir($dir)) {
//Убираем лишние элементы
if ($file != "." && $file != "..") {
//Выводим спиоск в браузер
$images[]=$file;
}
}
//Закрываем директорию
closedir($dir);
}
}В первом фрагменте осуществляем сканирование директории и сбор имен файлов в массив $images[].
Для реализации постраничной навигации необходимо:- Получить количество элементов массива;
- Вычислить количество страниц;
- Вычислить нижний и верхний предел для цикла for, внутри которого будет происходить листинг изображений.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//Получаем количество элементов в массиве
$amount=count($images);
//Делим на количество отображаемых на странице изображений
//и округляем в большую сторону
$pages = ceil($amount/$max);
//Принимаем входящую переменную, которая указывает номер страницы
$_p= $_GET['page'];
//Создаем вспомогательные переменные для навигации
//Если переменная $_p не задана
if(!$_p OR $_p =='') {
//Нижний предел
$nmin = 0;
//Верхний предел
$nmax=$max-1;
}
else {
$nmin = ($_p*$max)-$max ;
$nmax=($max*$_p)-1;
}А теперь давайте разберем этот фрагмент. Если страница не задана ($_GET['page'] не существует или равна пустоте) мы используем пределы от $nmin до $nmax в первых фигурных скобках.По умолчанию в настройках указано вывод 5 картинок на страницу .Т.к. у массива первое значение имеет ключ 0, а не 1 ,то для того чтобы вывести 5 картинок цикл for необходимо запустить от 0 до 4 (0,1,2,3,4 картинка). Для первой страницы задача решается просто: мы “жестко” задаем нижний предел $nmin, а верхний $nmax получаем путем вычитания единицы из количества картинок, которое должно отображаться на странице.
Рассмотрим что происходит если $_p существует и к примеру равна 2. Т.к. на первой странице выводятся значения от 0 до 4, то на второй странице необходимо вывести от 5 до 9 (5,6,7,8,9 картинка). Для того чтобы получить нижний предел, мы умножаем номер страницы на переменную $max и отнимаем $max.В результате таких действий мы получаем выражение: $nmin = 2×5-5=5 – т.е. получили необходимое значение. Верхний предел получаем путем умножения $max на номер страницы и вычитанием единицы. Пример: 2×5-1=9 – т.е. получили второй предел, до которого необходимо запускать цикл. Если страница третяя, то соответственно $nmin = 3×5 -5 = 10, и $nmax = 3×5-1 = 14. Надеюсь что я достаточно подробно все расписал. Далее следует цикл, внутри которого выводим уменьшенные изображения.
1
2
3
4
5
6
7echo '<h1>Фотогалерея</h1>';
for($i=$nmin;$i<=$nmax;$i++) {
if($images[$i]) {
echo '<a href="'.$url.'/'.$images[$i].'">';
echo '<img style="border:1px blue dashed;width:160px; height:120px;" src="'.$url.'/'.$images[$i].'"/>';
echo '</a> ';
} }Завершает наш скрипт блок навигации. Выше мы вычислили значение переменной $pages, которая указывает полное количество страниц, поэтому запускаем цикл в промежутке от 1 до $pages и выводим ссылки на страницы. Для того чтобы не запутаться в навигации, создаем 2 условия:
- Если текущая страница не равна $n – выводим ссылку;
- Если же $_p равна $n - это значит что мы находимся на этой странице, поэтому убираем ссылку.
1
2
3
4
5
6
7
8
9
10//Выводим номера страниц
echo "<br/><br/>";
for($n=1;$n<=$pages;$n++) {
if($_p != $n) {echo '<a href="index.php?page='.$n.'">['.$n.']</a> ';}
if($_p == $n) {echo '['.$n.'] ';}
}
?>Здесь можете посмотреть как это работает.
Фотогалерея с расширенными возможностями
Вторая версия галереи будет доработана и позволит составлять описания к изображениям. Для хранения описаний изображений будет использоваться БД MySQL. Разделим скрипт на 2 части – пользовательская и административная.
- Пользовательская часть будет выводить превьюшки (thumbnail’ы) изображений, при нажатии на которые происходит увеличение. Для этого будет задействовано немного javascript’а, он поможет нам при создании всплывающего окна, в которое будем подгружать полноразмерное изображение.
- Административная часть будет отвечать за upload фоток и составления описания к ним.
Изображения будут храниться в папке gallery. Перед тем как приступить к программированию необходимо создать таблицу gallery в базе данных. Для хранения данных нам потребуются три поля:
- img_name – имя файла. Тип данных – VARCHAR. В этом поле будет хранится название изображение. Максимальная длина равна 40 символов
- img_description – описание нашего изображение. Тип данных – VARCHAR. Это поле будет содержать описание нашего изображения.Максимальная длина описания составляет 250 символов.
- img_date – дата залития фотографии. Тип данных – VARCHAR. Максимальная длина 10.
Для создания таблицы откройте Phpmyadmin и выберите базу данных test (в вашем случае может быть любая другая).
В главном окне перейдите во вкладку SQL и вставте туда следующий запрос:
CREATE TABLE `gallery` (
`img_name` VARCHAR( 40 ) NOT NULL ,
`img_description` VARCHAR( 250 ) NOT NULL ,
`img_date` VARCHAR( 10 ) NOT NULL
) ENGINE = MYISAMРезультат выполнения запроса должен быть такой же как на скриншоте:
Административная часть
Я подготовил упрощенную версию без авторизации. Эту функцию вы можете самостоятельно прикрутить обратившись ко второму уроку. Представлю визуальный макет, чтобы в дальнейшем было проще работать.
- Блок управления находится в шапке страницы и не изменяется.
- Активный блок выполняет основную функцию. По умолчанию в нем происходит листинг изображений с описаниями (рядом с каждым изображением стоят служебные ссылки удалить/редактировать описание).
- Блок навигации осуществляет переходы по страницам.
admin.php
Блок управления
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<?php
//Поключаем конфиг
include("config.php");
//Подключаем функции
include("functions.php");
//Необходимо подключиться к БД
$link = mysql_connect($DBSERVER, $DBUSER, $DBPASS)
or die("Не могу подключиться" );
// сделать $DB текущей базой данных
mysql_select_db($DB, $link) or die ('Не могу выбрать БД');
//Блок управления
echo '<a href="?action=upload" alt="загрузить">[добавить изображение]</a><br/><br/>';В самом начале мы подключаем файл конфигурации и файл с функциями. Далее подключаемся к серверу MySQL и выбираем нужную базу используя свои настройки. После этого отображаем ссылку, которая ведет на загрузку файла.
Активный блок
По умолчанию в данном блоке отображаются изображения. Все данные извлекаются из базы и после этого выводятся в браузер. Для того чтобы извлечь имена картинок, мы создаем запрос $q1:
$q1 = mysql_query(”SELECT * FROM gallery LIMIT “.$min.”,”.$max.”");
$q1 = запрос(”ВЫБРАТЬ *(ВСЁ) ИЗ gallery ПРЕДЕЛ “.$min.”,”.$max.”");LIMIT позволяет читать данные по заданному пределу. Если требуется вывести 20 изображений на первую страницу, то в запросе указать LIMIT 0,20 . При переходе на вторую страницу в запросе указываем LIMIT 20,20 (выборка 20-ти строк от 21-ой строки). Использование атрибута LIMIT в запросе позволит организовать постраничную навигацию и выборку необходимых данных. Осталось лишь при помощи математических действий вычислить $min ($max берется из файла конфигурации). Прошу не путать с предыдущим примером, здесь навигация осуществляется по другому принципу.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48//Если не задано действие, осуществляем листинг
if($_GET['action'] == '') {
//Запрос на получение количества записей
$q = mysql_query("SELECT * FROM gallery");
$amount = mysql_num_rows($q);
//Делим количество файлов на количество размещения их на одной странице
//И округляем в большую сторону
$pages = ceil($amount/$max);
//Принимаем входящую переменную, которая указывает номер страницы
$_p = $_GET['page'];
//Создаем вспомогательные переменные для навигации
//Если не существую входящая переменная
if(!$_p OR $_p =='') {
$min = 0;
}
else {
//Умножаем номер страницы на $max и отнимаем $max
$min = ($_p*$max)-$max ;
}
//Производим выборку данных из базы
$q1 = mysql_query("SELECT * FROM gallery LIMIT ".$min.",".$max."");
echo '<table width="400" border="0" cellspacing="0" cellpadding="5">';
//Каждую запись считываем в массив и выводим в браузер
while($r=mysql_fetch_array($q1)) {
echo '<tr>';
echo '<td width="100"><img style="width:80px;height:60px" src="gallery/'.$r['img_name'].'"/></td>';
echo '<td align="center" width="300">'.$r['img_description'].'<br/>';
echo '<a href="admin.php?action=delete&fname='.$r['img_name'].'">[x]</a> ';
echo '<a href="admin.php?action=rename&fname='.$r['img_name'].'">[e]</td>';
}
echo '</tr><tr><td colspan="2">';
//Выводим номера страниц
for($n=1;$n<=$pages;$n++) {
if($_p != $n) {echo '<a href="admin.php?page='.$n.'">['.$n.']</a> ';}
if($_p == $n) {echo '<b>['.$n.'] </b>';}
}
echo '</td></tr></table>';
}Удаление файлов
Этот фрагмент очень похож на тот, что мы использовали в файловом менеджере. Здесь помимо удаления файла из папки ещё необходимо удалить данные из базы, поэтому мы создаем запрос $q2:
$q2 = “DELETE FROM gallery WHERE img_name=’”.$_GET['fname'].”‘”;
$q2 = “УДАЛИТЬ ИЗ gallery ГДЕ img_name=’”.$_GET['fname'].”‘”;Как видите ничего сложного. Запрос удаления данных выполняем после того как функция removefile() вернула положительный результат.
1
2
3
4
5
6
7//Удаление файлов
if($_GET['action']=='delete'){
$q2 = "DELETE FROM gallery WHERE img_name='".$_GET['fname']."'";
if(removefile($url."/".$_GET['fname']) !== FALSE) {
if(@mysql_query($q2)) {
header("location:admin.php");
} }}Изменение описания
Чтобы сменить описание необходимо отобразить форму, в которую должно подгружаться текущее описание. Для этого составляем запрос $q3:
$q3 =”SELECT img_description FROM gallery WHERE img_name=’”.$_GET['fname'].”‘”;
$q3 = “ВЫБРАТЬ img_description ИЗ gallery ГДЕ img_name=’”.$_GET['fname'].”‘”;Как видно из запроса, мы извлекаем описание соответствующее имени картинки img_name. После того как изменения внесены необходимо создать ещё один запрос, который изменит запись в базе данных:
$q4=”UPDATE gallery SET img_description=’”.$_POST['ndesc'].”‘ WHERE img_name=’”.$_POST['img_name'].”‘”;
$q4=”ИЗМЕНИТЬ gallery ПЕРЕПИСАТЬ img_description=’”.$_POST['ndesc'].”‘ ГДЕ img_name=’”.$_POST['img_name'].”‘”;Этот запрос меняет описание переданное в $_POST['ndesc'] у изображения, имя которого соответствует $_POST['img_name'].
Если возникли какие либо проблемы при записи, скрипт выдаст ошибку.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//смена описания
if($_GET['action']=='rename')
{
//Формируем запрос
$q3 ="SELECT img_description FROM gallery WHERE img_name='".$_GET['fname']."'";
//Выполняем запрос
$r3 = mysql_query($q3);
if(!$_POST['rename']) {
echo '<br/><form name="" action="?action=rename" method="post">';
echo 'Новое описание:<br/>';
echo '<textarea name="ndesc" rows=5 cols=20 wrap="off">'.mysql_result($r3,0,0).'</textarea>';
echo '<input name="img_name" type="hidden" value="'.$_GET['fname'].'">';
echo '<input type="submit" name="rename" value="ok"></form>'; }
else {
$q4 = "UPDATE gallery SET img_description='".$_POST['ndesc']."' WHERE img_name='".$_POST['img_name']."'";
if(@mysql_query($q4)) {
header("location:admin.php"); }
else {echo 'Ошибка <br/>';}
}
}Загрузка изображения
Это доработанный скрипт загрузки файла на сервер. Для того чтобы можно было загружать изображения до 1 мб, необходимо поправить функцию uploadfile(). Откройте файл с функцией, найдите условие которое проверяет размер файла и добавьте к максимальному один ноль ( if($FILE['FILE']['size'] != 0 AND $FILE['FILE']['size']<=1024000)).
Загрузка изображения происходит в 2 этапа. Сперва отображается форма, в которой необходимо выбрать файл, составить его описание и нажать на кнопку.
После ввода всех данных и нажатия на кнопку, происходит загрузка файла на сервер и запись описания изображения в таблицу gallery . Для этого составляем запрос $q5:
$q5 =”INSERT INTO gallery VALUES (’”.$_FILES['FILE']['name'].”‘,’”.$_POST['desc'].”‘,’”.date(”d-m-Y”).”‘)”;
$q5 =”ВСТАВИТЬ В gallery ЗНАЧЕНИЯ (’”.$_FILES['FILE']['name'].”‘,’”.$_POST['desc'].”‘,’”.date(”d-m-Y”).”‘)”;Если функция uploadfile() возвращает положительный результат, то осуществляем запрос к базе и делаем редирект на admin.php.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//Загрузка файла
if($_GET['action']=='upload')
{
if(!$_POST['up']) {
echo '<form action="?action=upload" method="post" enctype="multipart/form-data">';
echo 'Выберите файл (не более 1мб): <input type="file" name="FILE" size="20" /> ';
echo 'Описание:<br/><textarea name="desc" rows=5 cols=20 wrap="off"></textarea><br/>';
echo '<input type="submit" name="up" value="загрузить">';
echo '</form>';
}
else {
if(uploadfile($url,$_FILES)!== FALSE) {
$q5 ="INSERT INTO gallery VALUES ('".$_FILES['FILE']['name']."','".$_POST['desc']."','".date("d-m-Y")."')";
if(@mysql_query($q5)) {
header("location:admin.php"); }}
else {echo 'Ошибка <br/>';}
}
}
?>Файл функций
Этот файл содержит 2 функции, которые были написаны в предыдущем уроке. Первая функция отвечает за удаление файлов, вторая за upload файлов.
function.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36<?php
//Удалени файла
function removefile ($path) {
if(unlink($path)) { return TRUE; }
else { return FALSE; } }
//Функция загрузки файлов на сервер
function uploadfile($url,$FILE) {
//$url - текущая папка, $file - массив $_FILES
//Проверяем, существует ли имя.
if($FILE['FILE']['name']){
//Проверяем размер файла
if($FILE['FILE']['size'] != 0 AND $FILE['FILE']['size']<=1024000) {
//Проверяем загрузился ли файл на сервер
if(is_uploaded_file($_FILES['FILE']['tmp_name'])) {
//Перемещаем загруженный файл в необходимую папку $url
if(move_uploaded_file($FILE['FILE']['tmp_name'], $url."/".basename($FILE['FILE']['name']))) {
//Выводим сообщение что файл обработа и загружен
return TRUE;
}
else { return 'Произошла ошибка при перемещении файла в папку'.$url;}
}
else {return 'Прозошла ошибка при загрузке файла на сервер';}
}
else { return 'Размер файла не должен превышать 100Кб';}
}
else { return 'Файл должен иметь название';}
}
?>Файл конфигурации
В этом файле хранятся все настройки к нашей галерее.
config.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<?php
//Папка в которой будут храниться изображения
$url = "gallery";
//Данные для работы с MySQL
//Сервер, в большинстве случаев менять не требуется
$DBSERVER = "localhost";
//Пользователь и пароль
$DBUSER = "root";
$DBPASS = "";
//База данных
$DB = "test";
//Количество картинок на одной странице
$max = 4;
?>Пользовательская часть
Часто вижу отзывы что во всех моих уроках абсолютно отсутствует дизайн. Это верно, дизайн отсутствует, т.к. на его разработку уходит достаточно много время. В этот раз я решил исправить ситуацию и применил немного стилевых решений, благодаря которым галерея будет выглядеть уже не так серо и томно =). Все стили я вынес в отдельный файл style.css, который мы подключаем внутри тега head:
<head><link href=”style.css” type=”text/css” rel=”stylesheet” /></head>Вариант исполнения пользовательской части будет иметь следующую структуру:
Контент будет располагаться по центру внутри основного слоя шириной 800 пикселей. Каждая ячейка будет содержать уменьшенное изображение, дату размещения и описание. Ширина этой ячейки 200 пикселей, высота 180.
index.php
В самом начале файла index.php подключаем файл с функциями и файл конфигурации, который содержит все необходимые настройки.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71<?php
echo '<html xmlns="http://www.w3.org/1999/xhtml" lang="ru" xml:lang="ru">
<head>
<title>Фотогалерея</title>
<link href="style.css" type="text/css" rel="stylesheet" />
</head>
<body>
<center>';
include("config.php");
include("functions.php");
//Необходимо подключиться к БД
$link = mysql_connect($DBSERVER, $DBUSER, $DBPASS)
or die("Не могу подключиться" );
// сделать $DB текущей базой данных
mysql_select_db($DB, $link) or die ('Не могу выбрать БД');
//Далее, чтобы не переписывать код - скопируйте активный блок из админ части:
$q = @mysql_query("SELECT * FROM gallery");
$amount = @mysql_num_rows($q);
//Делим количество файлов на количество размещения их на одной странице
//И округляем в большую сторону
$pages = ceil($amount/$max);
//Принимаем входящую переменную, которая указывает номер страницы
$_p= $_GET['page'];
//Создаем вспомогательные переменные для навигации
//Если переменная $_p не задана
if(!$_p OR $_p =='') {
//Нижний предел
$min = 0;
}
else {
//Если же $_p задана то вычисляем нижний порог
$min = ($_p*$max)-$max ;
}
//Производим выборку данных из базы
$q2 = mysql_query("SELECT * FROM gallery LIMIT ".$min.",".$max."");
echo '<h1>Фотогалерея</h1>';
echo '<div align="center" style="width:800px;">';
//Каждую запись считываем в массив и выводим в браузер
while($r=mysql_fetch_array($q2)) {
echo '<div style="float:left;width:200px;height:180px;">';
echo "<a href=\"#\" onclick=\"javascript:window.open('gallery/".$r["img_name"]."','domru','top=100, left=100, width=800, height=600, scrollbars=yes, toolbar=no, menubar=no, location=no, directories=no' ); this.focus();\">";
echo '<img align="center" style="border:1px blue dashed;width:160px;height:120px" src="gallery/'.$r["img_name"].'"/><br/>';
echo '</a>';
echo '<span class="date">дата: '.$r["img_date"].'</span><br/>';
echo '<span class="text">'.$r["img_description"].'</span><br/>';
echo '</div>';
}
echo '<br/><div style="float:left;width:800px;">';
//======================БЛОК НАВИГАЦИИ=======================
//Выводим номера страниц
for($n=1;$n<=$pages;$n++) {
if($_p != $n) {echo '<span class="nav2"><a href="index.php?page='.$n.'">['.$n.']</a></span> ';}
if($_p == $n) {echo '<span class="nav">['.$n.']</span> ';}
}
echo '</div></div>';
?>В результате мы получим листинг изображений и навигацию. Чтобы сделать всплывающее окно мы использовали немного javascript’a:
javascript:window.open(’gallery/”.$r["img_name"].”‘,’gallery’,'top=100, left=100, width=800, height=600, scrollbars=yes, toolbar=no, menubar=no, location=no, directories=no’ ); this.focus();Эту функцию мы ставим под событие onclick, т.е когда человек кликает по картинке срабатывает ява-скрипт, который создает окно с соответствующим изображением. Снизу стандартно выводим номера страниц. Готовый пример моей фотогалереи можете посмотреть здесь.
Домашнее задание
Для того чтобы Вы лучше усвоили материал, я придумал небольшое задание. Необходимо будет доработать пользовательскую часть, а точнее написать небольшую функцию, которая будет проверять переменную $_GET['page'] на содержание лишних символов. Чтобы стало понятней, приведу скриншот. Обратите внимание на адресную строку и результат перехода по этому адресу:
Как видите, некоторые символы влияют на запросы к БД и вызывают ошибку. Чтобы такого не случилось, необходимо избавиться от них. В предыдущих уроках мы рассматривали варианты фильтрации произвольных символов, Вам же осталось это найти, осуществить проверку на тип входящих данных, прикрутить и протестировать.
Также советую сделать авторизацию для административной части.Скрипт фотогалереи
Скачать пример упрощенной фотогалереи – simple_gallery.zip
Скачать пример фотогалереи с расширенными возможностями – gallery.zip
Заключение
В этом уроке специально были приведены 2 примера. В каждом из них были использованы базовые функции, которые не должны вызывать вопросов. Этот материал подойдет как начинающим программистам , так и продвинутым. Замечания и предложения оставляем в комментариях =)
Блоговодам на заметку
Раскрашиваем блоки с кодом. PHP библиотеки и плагины для WordPress
Подпишись на RSS, впереди много интересного.81 Responses to “Урок 13.Создание фотогалереи на сайте. Менеджер изображений.”
Страницы: [9] 8 7 6 5 4 3 2 1 » Show All
Страницы: [9] 8 7 6 5 4 3 2 1 » Show All
Leave a Reply









Январь 19th, 2010 at 23:51
Спасибо за урок! Очень помогло!)))