• Продвинутая галерея на PHP и jQuery

    by  • 23.02.2010 • jQuery, php, программирование • Комментарии [3]

    screenshot 150x150 Продвинутая галерея на 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>

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

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

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

    Комментарии к "Продвинутая галерея на PHP и jQuery"

    1. 04.03.2010 at 21:55

      Доброе время суток! Я работаю журналистом в одном из новых издательств и как раз ныне пишу статью по подобной Вашей тематике! Не могли бы Вы дать разрешение на публикацию Вашего материала в нашем печатном изданииб естественно с указанием ссылки на данную статью! Заранее благодарен!

    2. 13.03.2010 at 16:25

      Здравствуйте! Ваш блог мне очень понравился, не могу подключить rss ленту, может я что-то не то делаю — подскажите пожалуйста куда нажимать, и работает ли она у Вас вообще? Заранее благодарен!

    3. admin
      13.03.2010 at 16:39

      Есть незаметная кнопка сверху и чуть более заметная внизу страницы. А вообще вы можете проследовать по ссылке http://vredniy.ru/rss

    Добавить комментарий

    Ваш e-mail не будет опубликован. Обязательные поля помечены *