jQueryプラグイン、Colorboxを使ったギャラリーを動的に生成するPHP

jQueryプラグイン、Colorboxを使ったギャラリーを動的に生成するPHP

ディレクトリを指定したら、その中の画像を全部読み込んでギャラリーページを動的につくってくれるものが欲しいなーと思い、書いてみました!


前提

140609-1

前に、このように header などを部品化したサイトを社内サーバに作った経緯がありまして。

今回WPは関係なく、このサイトに写真郡のギャラリーページを作りたい、というものです。

構想

140912-1

図のように photo というディレクトリの中に、年数別、更に日付別に分けたディレクトリがあって、そこに jpg がたくさん入っているとします。用途としては、忘年会とか社員旅行とかそういった毎年の写真群を、社内HPで閲覧できるようにするという感じです。画像ファイルだけアップロードしておけば、ギャラリーページを勝手に生成してくれるphpを書いてみたいなぁと思いました。

140912-2

このように、index.php には各写真郡へのリストが表示してあって、そこをクリックすると gallery.php へ遷移して、動的にギャラリーを出力してくれる、という感じで。

jQueryプラグインを使ってちょっとカッコ良さげにできたらなぁと思います。アップロードする写真群は、そのままポップアップされる画像になるので、予め適切な大きさにしておく必要があります。わたしの環境では、小さいモニタに合わせて800×600pxあたりにしました。

サムネイルも自動生成にしたい

ギャラリー生成時に使うサムネイル(例として100×75px程度のもの)も、こちらも予め用意してアップロードしておく必要があります。…が、これももっと楽したい…!((└(:3」┌)┘))

というわけで、今回は社内ネットワークからしかアクセスできない&管理者が限られてるということもあり、画像ディレクトリのパーミッションが 777 でも大丈夫そうなので、「サムネイルが存在しなかったら自動で生成する」という機能もつけてみます。

初回表示の時に生成されることになるので、初回のみ重くなります。新しく項目追加したら管理者が動作確認をかねて初回表示してやれば良いかなと思いまして。

Lightbox風jQueryプラグイン、ColorBox

有名なプラグインですよね。シンプルで使いやすくて大好きです!こちらを使わせていただきます。

DLして解凍したら、jquery.colorbox.js を js ディレクトリにアップロード。今回は example2 が気に入ったので、そのディレクトリ内の colorbox.css と images(ディレクトリ)も同じ場所へ。

140912-3

これを使って、簡単に書いてみるとこんな感じの構造になります。

/photo/gallery.html(仮)

<!DOCTYPE html>
<html>
	<head>
		<title>サンプル</title>
		<link rel="stylesheet" href="../js/colorbox.css" />
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
		<script src="../js/jquery.colorbox.js"></script>
		<script>
			$(document).ready(function(){
				$(".colorbox").colorbox();
			});
		</script>
	</head>
	<body>
		<ul>
			<li><a class="colorbox" rel="group1" href="1.jpg" title="1">1</a></li>
			<li><a class="colorbox" rel="group1" href="2.jpg" title="2">2</a></li>
			<li><a class="colorbox" rel="group1" href="3.jpg" title="3">3</a></li>
		</ul>
		<ul>
			<li><a class="colorbox" rel="group2" href="4.jpg" title="4">4</a></li>
			<li><a class="colorbox" rel="group2" href="5.jpg" title="5">5</a></li>
			<li><a class="colorbox" rel="group2" href="6.jpg" title="6">6</a></li>
		</ul>
	</body>
</html>

これだけで動きます!すごいですねー!10行目のかっこ内で要素を指定して(同じ名前にしてしまいましたが)、それを a タグに付加してやればOKです。同じ rel 名のものをグループ化して、ループ表示してくれます。

この例は必要最低限と思ってかなり削ってしまっています。パラメータを変えて動きをカスタマイズしたり、他にもいろいろできるのでググってみてくださいー!

構想

それでは、実際のギャラリーページをどういう形にしたいか書いてみます。

/photo/gallery.html(仮)

<!DOCTYPE html>
<html>
	<head>
		<title>サンプル</title>
		<link rel="stylesheet" href="/module/style.css">
		<link rel="stylesheet" href="/js/colorbox.css" />
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
		<script src="/js/jquery.colorbox.js"></script>
		<script>
			$(document).ready(function(){
				$(".colorbox").colorbox();
			});
		</script>
	</head>
	<body>
		<h1>タイトル</h1>
		<h2>備考</h2>
		<table id="photo">
			<tbody>
			<tr>
				<td><a class="colorbox" rel="gallery" href="2014/hoge/1.jpg" title="1.jpg"><img src="2014/hoge/s1.jpg" width="100" height="75" /></a></td>
				<td><a class="colorbox" rel="gallery" href="2014/hoge/2.jpg" title="2.jpg"><img src="2014/hoge/s2.jpg" width="100" height="75" /></a></td>
				<td><a class="colorbox" rel="gallery" href="2014/hoge/3.jpg" title="3.jpg"><img src="2014/hoge/s3.jpg" width="100" height="75" /></a></td>
			</tr>
			<tr>
				<td><a class="colorbox" rel="gallery" href="2014/hoge/4.jpg" title="4.jpg"><img src="2014/hoge/s4.jpg" width="100" height="75" /></a></td>
				<td><a class="colorbox" rel="gallery" href="2014/hoge/5.jpg" title="5.jpg"><img src="2014/hoge/s5.jpg" width="100" height="75" /></a></td>
				<td><a class="colorbox" rel="gallery" href="2014/hoge/6.jpg" title="6.jpg"><img src="2014/hoge/s6.jpg" width="100" height="75" /></a></td>
			</tr>
			</tbody>
		</table>
	</body>
</html>

こんなhtmlを生成するように、phpを書いていきたいと思います!リンクはテキストではなくサムネイル画像に貼られるようにして、元画像が XXX.jpg だったら、サムネイルは sXXX.jpg という名前のルールにします。

あとは、タイトルや備考をつけたり、テーブルにしてみたり。横にいくつ並べるかは、自由に指定できるようにしたいですね。

実装

/module/header.php

<?php
$slug = explode('/', $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
$navi = ($slug[1] == '') ? 'home' : $slug[1];
?>
<!DOCTYPE html>
<html>
	<head>
		<title>サンプル</title>
		<link rel="stylesheet" href="/module/style.css">
<?php if( $navi == 'photo' ): //該当ページのみcolorboxを読み込む ?>
		<link rel="stylesheet" href="/js/colorbox.css" />
		<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
		<script src="/js/jquery.colorbox.js"></script>
		<script>
			$(document).ready(function(){
				$(".colorbox").colorbox();
			});
		</script>
<?php endif; ?>
	</head>
	<body>

現在のディレクトリを判定して、該当ページのみ、ハイライトより中に colorbox 設定を読み込んでいます。冒頭でも紹介しましたが、こちらの記事に、グローバルナビ部分も合わせて詳しく書きましたのでご参照いただければ。

/photo/index.php

<?php
include("../module/header.php");
?>
		<h1>2014</h1>
		<form action="gallery.php" method="post">
			<input type="submit" name="title" value="新人歓迎会" />
			<input type="hidden" name="notes" value="2014/4/20" />
			<input type="hidden" name="path" value="2014/140420/" />
		</form>
		<form action="gallery.php" method="post">
			<input type="submit" name="title" value="野球大会" />
			<input type="hidden" name="notes" value="2014/6/6" />
			<input type="hidden" name="path" value="2014/140606/" />
		</form>
		<form action="gallery.php" method="post">
			<input type="submit" name="title" value="忘年会" />
			<input type="hidden" name="notes" value="2014/12/10 ××にて" />
			<input type="hidden" name="path" value="2014/141210/" />
		</form>
	</body>
</html>

こちらはギャラリーページへ遷移する前のインデックス。formを使って、タイトル・備考・画像へのパスを書いておきます。このボタンを押すとその内容を gallery.php に引き渡すことになります。

機能はボタンのまま、見た目をテキストリンクのようにすることも出来ます。こちらに書いたことがあります。

/photo/gallery.php

<?php
foreach (array('title', 'notes', 'path') as $v) {
	$$v = (string)filter_input(INPUT_POST, $v); //情報取得
}
if ( file_exists($path) == false ) {
	header("Location:index.php"); //パスが存在しなければindexへジャンプ
}

//1.画像ファイル名を配列に格納(サムネイルがなければ関数で生成)

//2.サムネイル生成関数

include("../module/header.php");
?>
		<h1><?php echo $title; ?></h1>
		<h2><?php echo $notes; ?></h2>
		//3.テーブル出力
	</body>
</html>

ギャラリーページ。全部一度に書くと長くなるので、ハイライト部分を省略して順に解説していきます。

1.画像ファイル名を配列に格納(サムネイルがなければ関数で生成)

$perms = substr(sprintf('%o', fileperms($path)), -4); //パーミッション取得
if ( $perms == '0777' ) {
	$i = 0;
	foreach(glob($path . "*") as $value) { //ディレクトリ内を見る
		$file = str_replace($path, '', $value); //ファイル名のみ取得
		if ( substr($file, 0, 1) != 's' && (substr($file, -4) == '.jpg' || substr($file, -4) == '.JPG') ){
			$files[$i] = $file; //元画像ファイル名のみ配列に格納
			if ( file_exists($path.'s'.$file) == false ) { img_rsz($path, $file); } //サムネイルが存在しなければ生成
			$i++;
		}
	}
}

こちらのコードはサムネイルが無かったら自動生成するので、予め1行目で指定ディレクトリのパーミッションを取得して、777 でないと処理を行わないようになっています。

指定ディレクトリ内(サブディレクトリまでは見ません)のファイル名を取得して、頭が s でない(サムネイルでない)こと、拡張子が .jpg または .JPG かどうか判断して(6行目)、条件を満たしたものだけ配列に格納(7行目)しています。

8行目で、s を付けたファイル名が存在するか確認して、なければ img_rsz() という関数に飛ばします。

$i = 0;
foreach(glob($path . "*") as $value) { //ディレクトリ内を見る
	$file = str_replace($path, '', $value); //ファイル名のみ取得
	if ( substr($file, 0, 1) != 's' && (substr($file, -4) == '.jpg' || substr($file, -4) == '.JPG') ){
		$files[$i] = $file; //元画像ファイル名のみ配列に格納
		$i++;
	}
}

サムネイルを自動生成しない場合は、こんな感じ。

2.サムネイル生成関数

function img_rsz($path, $file){ //サムネイル生成関数
	list($width, $height) = getimagesize($path.$file); //サイズ取得
	if ( $width > $height ){
		//横長写真
		$newwidth = 100; //横幅指定
		$newheight = abs($newwidth * $height / $width); //縦幅を計算
	} else {
		//縦長写真
		$newheight = 75; //縦幅指定
		$newwidth = abs($newheight * $width / $height); //横幅を計算
	}
	$image_p = imagecreatetruecolor($newwidth, $newheight); //空の画像を作成
	$image = imagecreatefromjpeg($path.$file); //元の画像をコピー
	imagecopyresampled($image_p, $image, 0, 0, 0, 0, $newwidth, $newheight, $width, $height); //サイズ変更
	imagejpeg($image_p, $path.'s'.$file); //画像の出力
}

横長写真なら5行目、縦長写真なら9行目の大きさが基準になり、元画像のサイズから縦横比固定で縮小した画像を生成します。サムネイルを手動でアップする場合はこの関数は必要ありません。

3.テーブル出力

<?php
if ( $perms != '0777' ) {
	echo "<p>管理者へ:画像ディレクトリのパーミッションを777へ変更してください。</p>\n";
} else {
	$n = 10; //横に並べる数

	$table = '<table id="photo">'."\n";
	$table .= "\t<tbody>\n";
	$table .= "\t<tr>\n";
	$i = 0;
	foreach ($files as $file) {
		list($width, $height) = getimagesize($path.'s'.$file);
		$table .= "\t\t".'<td><a class="colorbox" rel="gallery" href="'.$path.$file.'" title="'.$file.'"><img src="'.$path.'s'.$file.'" width="'.$width.'" height="'.$height.'" /></a></td>'."\n";
		$i++;
		if ( $i % $n == 0 ) { //行を変える
			$table .= "\t</tr>\n";
			if ( $i < count($files) ) { $table .= "\t<tr>\n"; }
		}
	}

	if ( $i % $n != 0 ) {
		while ( $i % $n != 0 ) {
		$table .= "\t\t<td> </td>\n"; //余ったtdを埋める
		$i++;
		}
		$table .= "\t</tr>\n";
	}
	$table .= "\t</tbody>\n";
	$table .= "</table>\n";

	echo $table;
}
?>

サムネイルを手動でアップする場合は2~4, 32行は必要ありません。5行目はテーブルの横の数になります。サムネイルの大きさとページの横幅によって適切な数値が変わると思います。CSSはおこのみで~。

追記:ulリストで出力

後で気づいたんですがテーブルにする必要全然ない…!Σ(゚д゚lll) 普通にulリストで作っておけば行変えるとかもいらないですねw

<?php
if ( $perms != '0777' ) {
	echo "<p>管理者へ:画像ディレクトリのパーミッションを777へ変更してください。</p>\n";
} else {
	$txt = '<ul id="photo">'."\n";
	foreach ($files as $file) {
		list($width, $height) = getimagesize($path.'s'.$file);
		$txt .= "\t".'<li><a class="colorbox" rel="gallery" href="'.$path.$file.'" title="'.$file.'"><img src="'.$path.'s'.$file.'" width="'.$width.'" height="'.$height.'" /></a></li>'."\n";
	}
	$txt .= "</ul>\n";

	echo $txt;
}
?>

こんなに短くなっちゃいましたw あとはCSSでどうにでもなりますね!

以上です!いかがでしたでしょうか?きっかけは、「ギャラリーちょうめんどくさい…!どうにかして更新楽したい…!!」という一心でした…w phpはまだあまり自信がないのですが、どなたかのお役にたてたら幸いです!

公開日:2014/09/12
更新日:2014/09/18

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)

YouTubeでQ&Aコンテンツを企画しています

運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。