画像一覧表示系

昔で言うところの、画像ギャラリー(?)にしたい、という要望が未だにあったり。
または、過去のギャラリーとしているものを見返すと、まぁまぁな量の画像が載っていたり。

で、相変わらずな、低レベルソースコード(やんわり書けなかった…クソコードとか書きかけた)なものが散見される。<あくまでも過去の更新者に対して。

li で並べて、flex で自動的に流していく、まではまぁ良かろう。
※ちょい前の案件だと、float してて、ドツキ回したろか、とか思った。

なぜ、全部 HTML で書く?
それこそ、jQuery とかで、探せへんの。。。?

か、テメーで管理出来てるサーバに載っけるなら、PHP で書くとか。ソースコードの管理しなくて良い・極力ソースコード記述での漏れ/ミスを防ぐように、考慮してもらいたいもんです。
最終的には、自分たちのチェック自体の時間も減り、ミスも減りますので。

というわけで、
1) 画像格納のディレクトリを決定
2) 固定の HTML を書き出す PHP のスクリプトを考える
3) ローカル動作確認>テストサーバ確認>本番サーバ確認 で、PHP の動作・バージョン挙動など確認

で、特定のディレクトリに、画像を放り込んでおけば表示されてるよ、という状態を、デフォルトとしていきたい。
適当に検索すりゃー出てくるけどね。検索とゎ。。。ということも、また後日。

■PHP 利用、特定のディレクトリ内のファイルを Loop して取得。

<?php
$photo = '/img/slick/';#photo dir
$path = $_SERVER['DOCUMENT_ROOT'].$photo;
if ($dh = opendir($path)) {#glob より速いらしい…
    while(($p_file = readdir($dh)) !== false) {#filename
		if ($p_file === '.' || $p_file === '..') {#ディレクトリの、「.」と「..」以外を取得
		continue;
		}
		echo '<li><img src="'.$photo.$p_file.'" alt="Photo_'#src, alt
		.basename(($p_file), '.jpg').'"></li>'#alt用 拡張子を外してファイル名のみ採用
		."\n".'					';#HTML print
    }
    closedir($dh);
}
?>

echo の最後の改行コード『\n』は、ソースコードが展開された時に、li で改行されて並んでいてもらいたい場合のみ。なお、改行コードは、シングルクォーテーションで囲っていると文字列と判定されるらしく、「\n」と表示されてしまう。必ずダブルクォーテーションで囲うように、要注意(ということを、コレを作ってるときに初めてわかった。そんなこと書いてる PHP 解説無かったけど…)。

if で opendir していなければ、closedir が無い形でも、動作するもよう。
改↓↓↓

<?php
$photo = '/img/slick/';#photo dir
$path = __DIR__.$photo;
$dh = opendir($path);#glob より速いらしい…
    while(($p_file = readdir($dh)) !== false) {#filename
		if ($p_file === '.' || $p_file === '..') {#ディレクトリの、「.」と「..」以外を取得
		continue;
		}
			echo '<li><img src="'.$photo.$p_file.'" alt="Photo_'#src, alt
			.basename(($p_file), '.jpg').'"></li>'#alt用 拡張子外し
			."\n".'					';#HTML print
    }
?>

他の方法、と思って検索すると、ソースコード的にも見やすいため、glob が候補として出てくるが、ファイル数が多いような場合には、サーバサイドでの動作が、遅くなるらしい。
それに対して、opendir, readdir を使用すると、27倍(と、比較しているサイトがあった)速いという例も挙がるほど。話半分としても、10倍速いのであれば、そちらを使ってみようか、と思う。

一覧取得で、ディレクトリを示す「.」「..」を排除する上記パターンと、特定の拡張子を持つファイルを指定して取得する下記、2方法が考えられる。

<?php
$photo = '/images/gallery/2023/';#photo dir
$path = $_SERVER['DOCUMENT_ROOT'].$photo;
$dh = opendir($path);#glob より速いらしい…
	  while($item = readdir($dh)) {
		  if(pathinfo($path.$item)['extension'] === 'jpg')#特定の拡張子のファイルのみ取得
echo '<div class="gallery_img"><a href="'.$photo.$item.'" data-lightbox="group">
	<img src="'.$photo.$item.'" alt="Photo_'.basename(($item), '.jpg').'"></a></div>'."\n";#HTML print
	  }
?>

ディレクトリの排除の場合より、少しだけソースコードが短くできるかも。
画像の種類特定とするほうが、動作内容はわかりやすいかもしれない。

その他、取得するファイルによっては、一覧取得の段階で、何かしらの分岐・選択をおこなう場合が考えられる。その場合は、結局 glob で操作しないといけなくなるようなので、最初から glob で処理してしまうほうが、ソースコードとしては、見やすくわかりやすくなりそうだ。

■参考)ディレクトリ内に、*_s.jpg なサムネイル画像と、クリックオープン用の _s が付かないファイルが、まとめて存在している場合。

<?php
$photo = '/images/gallery/2023/';#photo dir
$files = glob($_SERVER['DOCUMENT_ROOT'].$photo.'*_s.jpg');#photo file
foreach ($files as $key => $value) {#file loop get
	$p_file = $photo.basename($value);#_s file name get
	$name_only = basename($value, '_s.jpg');#filename
	echo '<div class="gallery_img"><a href="'.$photo.$name_only
		.'.jpg" data-lightbox="group"><img src="'.$p_file.'" alt="Photo_'.$name_only.'"></a>
		</div>'."\n";#HTML print
}
?>

取得の考え方として、表示用と、サムネイル用がセットで存在するということで、glob で取得する際に、_s.jpg のファイルだけをサーチして取得する、と設定する。
p_file に、取得するファイルがセットされる(xxx_s.jpg で取得)。
a タグのリンクするソースには、basenameから、_s.jpg を除いてから、.jpg を追加することで、ノーマルサイズの画像を取得できる(xxx.jpg を取得)。
img で表示するのは、_s.jpg なので、p_file のままをセット。
となる。

この記事が気に入ったらサポートをしてみませんか?