Галерея на PHP и jQuery

Сегодня мы с вами разработаем небольшую галерею, у которой будет подобие админки с возможностью добавления новых и удалением имеющихся фотографий. Самое интересное в этой галерее будет возможность задать размеры миниатюры в реальном времени, сразу наблюдая за изменениями. Код писался на скорую руку, поэтому ни о какой безопасности и юзабилити речь не идет. Но, если кому покажется интересным создания галереи с нуля, легко сможет добавить недостающий функционал и расширить уже имеющийся.

Также вы можете ознакомиться с заметкой Создание миниатюр на PHP

Создание админки

Для начала создадим файл config.php, в котором будем хранить некоторые конфигурационные данные. В первую очередь это секретной слово, которое поможет нам обезопаситься от посторонних глаз. У меня галерея располагается в папке http://localhost/resizilka. Исходя из этого и будет организован конфиг.

1
2
3
4
5
6
<? php
$galleryFolder = 'gallery';
$thumbsFolder = 'gallery/thumbs';
$host = 'http://localhost/resizilka';
$secretKey = 'fsdfs432fxD';
?>

$galleryFolder – папка на сервере, где будут располагаться изображения.

$thumbsFolder – папка, в которой будут храниться миниатюры.

$host – для вывода картинок в галерее.

$secretKey – своего рода пароль, при вводе которого мы попадаем в админку.

Теперь о админке, которая будет состоять из одного файла. Конечно, если бы их было больше, можно было упростить структуру.
В начале файла нам понадобится подключить конфигурационный файл и открыть сессию (главное, чтобы до открытия сессии ничего не выводилось, а то вылезет ошибка). Файл admin.php

1
2
3
4
5
6
7
8
9
10
<?php require_once 'config.php';
session_start();
if ($_SESSION['secretkey'] != 'passed') {
    if ($_GET['secret'] != $secretKey) {
        die('access denied');
    } else {
        $_SESSION['secretkey'] = 'passed';
    }
}
?>

Для того, чтобы войти в админку нам нужно проследовать по адресу http://localhost/resizilka/admin.php?secret=fsdfs432fxD (в конце адреса ключ из конфигурационного файла)

Дальше вставим html-заголовки и подключим нужные стили и скрипты (помимо jQuery используется плагин Resizable). Скачать их и все файлы проекта, вы можете по ссылке в конце заметки.

1
2
3
4
5
6
7
8
9
10
11
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf8" />
        <script type="text/javascript" src="js/jquery.js"></script>
        <script type="text/javascript" src="js/interface.js"></script>
   <link rel="stylesheet" type="text/css" href="styles/main.css" />

    </head>
    <body>

Так как у нас все располагается в одном файле, нам нужна проверка не загружен ли файл, если да, то создаем миниатюру, если нет, то выводим только форму для добавления новых и таблицу с крестиком для удаления имеющихся.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
if(!isset($_FILES['filename'])) {?>
<h2>Загрузка файлов на сервер</h2>
<form method="post" enctype="multipart/form-data" action="admin.php">
    <input type="file" name="filename" />
    <input type="submit" value="Загрузить" />
</form>
<h2>Имеющиеся фотки</h2>
<?php
$images = scandir($thumbsFolder);
echo "<table cellpadding=\"10\">";
unset ($images[0]);
unset ($images[1]);
foreach ($images as $image) {
    echo "<tr><td><img src=\"" . $host . '/' . $thumbsFolder . '/' . $image . "\" /></td>\n";
    echo "<td><a href=$host/erase.php?ss=$image>x</a></td></tr>";
}
echo "";
?>

unset‘ами мы исключаем вывод . и ..

Таблица представляет из себя строки из картинки и крестика, при нажатии на который мы удаляем картинку, отдавая ее в руки скрипту erase.php Текст файла для удаления:

1
2
3
4
5
<?php
require_once 'config.php';
unlink($thumbsFolder . '/' . $_GET['ss']);
header("Location: $host/admin.php");
?>

После удаления переходим на главную страницу админки. За это отвечает редирект.

Теперь ветка алгоритма, если мы что-то загрузили на сервер в файле admin.php

1
2
3
4
5
6
7
8
9
10
11
12
<?php } else {
    echo $_FILES['filename']['type'];
    $picFilename = $_FILES['filename']['name'];
    if (copy($_FILES['filename']['tmp_name'],
            $galleryFolder . '/' . $picFilename)) {
        $picPath = $galleryFolder . '/' . $picFilename;


    $picData = getimagesize($picPath);
    $picWidth = $picData[0]; $picHeight = $picData[1];
    echo $picWidth . ' x ' . $picHeight;
?>

Т.к. галерея делалась для себя, здесь много debug-информации. Например, тут выводятся размеры картинки, которые мы будет использовать далее.

Сразу подготовим функцию для ресайзинга, которая в качестве параметров принимает картинку-источник и картинку-назначение, координаты левого верхнего угла и размеры. Это и будет наш файл cutting.php, к которому мы будем обращаться посредством AJAX-запроса с помощью jQuery.

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
<?php
require_once 'config.php';
$src = $galleryFolder . '/' . $_GET['src'];
$dest = $thumbsFolder . '/' . time() . $_GET['src'];
$x = $_GET['x'];   $y = $_GET['y'];
$width = $_GET['width'];    $height = $_GET['height'];
imageCutting($src, $dest, $x, $y, $width, $height);
function imageCutting($src, $dest, $x, $y, $width, $height, $rgb = 0xffffff)
{
    if(!file_exists($src)) {
        echo "$ src not exist";
        return FALSE;
    }
    $size = getimagesize($src);
    if ($size === FALSE) {
        echo "cannot get image size";
        return FALSE;
    }

    $format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1));
    $icFunc = 'imagecreatefrom' . $format;
    if (!function_exists($icFunc)) {
        echo "function does not exist";
        return FALSE;
    }

    $isrc = $icFunc($src);
    $idest = imagecreatetruecolor($width, $height);

    imagefill($idest, 0, 0, $rgb);
    imagecopyresampled($idest, $isrc, 0, 0, $x, $y, $width, $height, $width, $height);

    imagejpeg($idest, $dest, 80);

    imagedestroy($isrc);
    imagedestroy($idest);
    echo "all done <br /><b>" . $dest . '</b><br /> was created';
    return TRUE;
}
?>

Теперь перейдем к разметке и программированию на стороне клиента. Т.к. почти весь функционал у нас находится в одном файле, нам будет намного удобнее передавать значения некоторых переменных в JavaScript.

Продолжим кропотать над 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
<div id="container"
    style="position: relative;
    width: <?php echo $picWidth; ?>
px;
     height: <?php echo $picHeight; ?>px;">
<img src="<?php echo $picPath; ?/>" />
<div id="resizeMe">
    <div id="resizeSE"></div>
    <div id="resizeE"></div>
    <div id="resizeNE"></div>
    <div id="resizeN"></div>
    <div id="resizeNW"></div>
    <div id="resizeW"></div>
    <div id="resizeSW"></div>
    <div id="resizeS"></div>
</div>
</div>
<br />
<div style="position: absolute;
   right: 0; top: 0; width: 200px;">

    <b>Позиция</b>
    <br />
    x: <span id="left"></span>
    &nbsp;
    y: <span id="top"></span>
    <br />
    <button>Закончить</button>
    <div id="info"></div>
</div>

1
id="resizeMe"

и все вложенные в него элементы отвечают за квадратик с рамкой и маркерами для ресайза. Добавим немного уличной магии в виде JavaScript.

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
<script type="text/javascript">
var pic_x, pic_y;
$(document).ready(
function()
{
$('button').click(function()
{
if (pic_x == undefined) pic_x = 0;
if (pic_y == undefined) pic_y = 0;
var q;
q = 'src=<?php echo $picFilename; ?>&';
q = q + 'x=' + pic_x;
q = q + '&y=' + pic_y;
q += '&width=200';
q += '&height=150';
$('div#info').load('cutting.php?' + q);
})
$('#resizeMe').Resizable(
{
minWidth: 200,
minHeight: 150,
maxWidth: 200,
maxHeight: 150,
minTop: 1,
minLeft: 1,
maxRight: <?php echo $picWidth; ?>,
maxBottom: <?php echo $picHeight; ?>,
dragHandle: true,
onDrag: function(x, y)
{
pic_x = x;
pic_y = y;
$('#left').html(x + 'px');
$('#top').html(y + 'px');
},
handlers:
{
se: '#resizeSE',  e: '#resizeE',
ne: '#resizeNE',  n: '#resizeN',
nw: '#resizeNW',  w: '#resizeW',
sw: '#resizeSW',  s: '#resizeS'
}/*,
onResize : function(size, position) {
$('#left').html((position.left-50)+'px');
$('#top').html((position.top-50)+'px');
$('#width').html(size.width);
$('#height').html(size.height);
}*/

}
)
}
);
</script>

Во второй строчке которого мы объявляем переменные, чтобы хранить в них координаты левого верхнего угла миниатюры. При нажатии на кнопку в 6 строке мы собираем параметры в одну строку и отправляем с помощью jQuery скрипту cutting.php, получая при этом какой-либо ответ без перезагрузки страницы. Если вы хотите, чтобы имелась возможность ресайзить квадратик, нужно задать отличные величины в строчках 20-23, раскомментировать строки 42-48 и в строках 14 и 15 передавать ширину и высоту соответственно.

Главная страница галереи

Осталось только сделать вывод картинок, которые находятся в папке миниатюр (в config.php за эту папку отвечает переменная $thumbsFolder).

Это и будет наш 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
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<script type="text/javascript" src="js/jquery.js"></script>
<link rel="stylesheet" type="text/css" href="styles/main.css" />
</head>
<body>
<?php
require_once 'config.php';
$images = scandir($thumbsFolder);
echo "<table cellpadding=10>";
unset ($images[0]);
unset ($images[1]);
foreach ($images as $image) {
if (($i % 3 == 0) && ($i!=0)) echo "<tr>";
if ($i == 0) echo "</tr><tr>";
echo "<td><img src=\"" . $host . '/' . $thumbsFolder . '/' . $image . "\" /></td>\n";
$i++;
}
if ($i % 3 != 0) echo "</tr>";
?>
</body>
</html>

В этом файле мы всего лишь выводим наши миниатюры в таблице в три столбца.

Эта несложная в реализации галерея имеет право на существование, если ее довести до ума и продумать дизайн. Но это уже все на ваше усмотрение.

Скачать исходники