1. 導入
Webサイトで画像をタイル状に並べるレイアウトは、Pinterestのようなモダンなデザインでよく用いられます。一般的にはクライアントサイドのJavaScriptライブラリが主流ですが、あえてPHPで実装することで、初期表示の高速化や、JavaScriptに依存しない軽量なコンテンツ生成が可能になります。今回は、サーバーサイドで画像の高さを計算し、各カラムの合計高さを均一に保つロジックを解説します。
2. 基礎知識
この実装の核となるのは「貪欲法(Greedy Algorithm)」に近い考え方です。
・カラムの管理: 指定されたカラム数分の配列を用意し、現在の「合計高さ」を保持します。
・ソート処理: 画像を追加するたびに、最も高さが低いカラムを特定し、そこに画像を追加していきます。
・getimagesize関数: PHPの標準関数で、画像ファイルからピクセル単位のサイズ情報を取得します。これにより、レンダリング前に各画像の高さを把握できます。
3. 実装/解決策
実装のポイントは、foreachループ内で毎回カラムの合計高さをソートし、最小値を持つカラムを特定することです。これにより、視覚的にバラつきの少ないタイル状の配置が自動的に生成されます。
4. サンプルプログラム
以下は、ディレクトリ内の画像を読み込み、指定したカラム数に振り分ける実用的なコードです。
/
function renderGallery($files, $column) {
// 各カラムの合計高さを記録する配列を初期化
$heightTotal = array_fill(0, $column, 0);
// 各カラムに振り分けられた画像リスト
$columns = array_fill(0, $column, []);
foreach ($files as $file) {
// 現在最も高さが低いカラムのインデックスを取得
asort($heightTotal);
$targetIndex = key($heightTotal);
// 画像のサイズを取得
$size = getimagesize($file);
$height = $size[1] ?? 0; // 高さを取得(失敗時は0)
// 該当カラムに画像を追加し、合計高さを更新
$columns[$targetIndex][] = $file;
$heightTotal[$targetIndex] += $height;
}
// HTML出力
foreach ($columns as $columnFiles) {
echo ‘
foreach ($columnFiles as $file) {
echo ‘
}
echo ‘
‘;
}
}
// 使用例
$dir = “images/”;
$files = glob($dir . “.{jpg,png,gif}”, GLOB_BRACE); // 指定拡張子の画像のみ取得
renderGallery($files, 3);
?>
5. 応用・注意点
・パフォーマンスの考慮: サーバーサイドで毎回getimagesizeを呼ぶとディスクI/Oがボトルネックになります。本番環境では、画像アップロード時にDBへサイズ情報を保存しておき、そこから参照するように設計するのがベストプラクティスです。
・レスポンシブ対応: この手法は静的なHTMLを出力するため、ブラウザのリサイズに合わせて動的に配置を変えることはできません。ウィンドウサイズが変わるごとに画像を再配置したい場合は、CSSのGridレイアウト(grid-template-columns)を使用するか、素直にJavaScriptのMasonryライブラリを併用することを推奨します。
・画像読み込み: 大量の画像を一度に処理する場合、メモリ使用量に注意してください。必要に応じてページネーションを実装してください。