Script PHP de galerie d'images utilisant CSS grid

Ce script PHP permet d'afficher dans une page web, une galerie d'images en utilisant CSS grid (pour un alignement parfait et automatique des images et ce, quelque soit la taille de la fenêtre du navigateur, plus besoin d'utiliser float, clear et cie !).

On affiche des miniatures, et clic dessus pour voir l'image en taille réelle.

Je sais bien que cela existe déjà, mais j'aime bien créer par moi-même et pas toujours utiliser les "trucs" tout faits. Je peux dire comme dans la pub : "C'est moi qui l'ait fait !" 

Requis

Optionnel

Utilisation

Dans une page PHP on appellera la fonction galerie :

echo galerie('folder=mon_dossier&parametre1=value1&parametre2=value2 ...');

Si on crée ses pages web à l'aide d'un l'éditeur WYSIWYG comme TinyMCE (que j'utilise), on utilisera le shortcode galerie (fonction shortcode basique developpée par mes soins, un peu à la façon des shortcodes de WordPress) :

[galerie:folder=mon_dossier&parametre1=value1&parametre2=value2 ...]

Paramètres

Fonctions PHP

<?php
/**
 * Affichage d'une galerie de photos (utilisant css grid)
 * 02/02/2022
 * Mise à jour : 15/04/2024
 * Modification 19/12/2024 : les miniatures sont dans un dossier séparé (ex : 70x70)
 *				27/08/2026 : affichage infos (infos.php) sous les miniatures (option "caption")
 * 				03-09-2026 : correction bug quand erreur dans fichier infos.php
 * www.nonoweb.net
 */

/**
 * constantes
 */
define('MSG_FOLDER_MISSING', 'Paramètre obligatoire <strong>«&#8239;folder</strong>&#8239;» non spécifié.');
define('MSG_ERREUR_AFFICHAGE_GALERIE', 'Shortcode <strong>galerie</strong>&nbsp;: ');
define('MSG_PATH_NOT_EXIST', 'Dossier <strong>«&#8239;%s</strong>&#8239;» absent.');
define('MSG_NO_THUMBNAILS_TO_DISPLAY_2', 'Pas de miniature dans le dossier <strong>«&#8239;%s</strong>&#8239;».');
define('MSG_NO_FILE_INFOS', 'Fichier <strong>«&#8239;infos.php</strong>&#8239;» absent dans le dossier<strong>«&#8239;%s</strong>&#8239;».');
// Icône Font Awesome (https://fontawesome.com/v4/get-started/)
define('ICON_WARNING', '<i class="fa fa-exclamation-triangle margin-right" aria-hidden="true"></i>');
define('FORMAT_THUMBNAIL', '_%sx%s');
define('MSG_FOLDER_SMALL_MISSING', 'Dossier des miniatures <strong>«&#8239;%s</strong>&#8239;» absent.');

/**
 * parcourt un dossier $f
 * retourne un tableau contenant les images de la forme xxxxx_99x99.ext avec l'(les) extension(s) contenue dans le tableau $e
 * nombre d'images à afficher $n
 * $exc : images exclues (paramètre excluded de la fonction galerie)
 */
function searchExtFolder($f, $e, $n, $exc, $d) {
$tbl_small = array();
// $small = sprintf(FORMAT_THUMBNAIL, $d, $d);
$cpt = 0;
	if ($handle = opendir($f)) {
		while ((false !== ($file = readdir($handle))) && ($cpt != $n || $n == '')) {
			// no . nor ..
			if ($file != '.' && $file != '..') {
				foreach ($e as $ex) {
					if (preg_match("/.".$ex."/i",$file)) {
						if (!is_dir($f.'/'.$file)) {
							if (!in_array(removeSmall($file, $d), $exc)) {
									$tbl_small[] = $file;
									$cpt++;
							}
						}
					}
				}
			}
		}
		closedir($handle);
	}
	/*
	test($tbl_small, 't=$tbl_small&l='.basename(__FILE__).':'.__LINE__.' ');
	test($cpt, 't=$cpt&l='.basename(__FILE__).':'.__LINE__.' ');
	test($exc, 't=$exc&l='.basename(__FILE__).':'.__LINE__.' ');
	*/
    return $tbl_small;
}

/**
 * Function Usage	: echo galerie('folder=mon_dossier_des _images&parametre1=value1&parametre2=value2 ...')
 * Shortcode Usage	: [[galerie:folder=mon_dossier_des _images&parametre1=value1&parametre2=value2 ...]]
 * Paramètre folder obligatoire !
 * Par défaut tous les dossiers des galeries se trouvent dans un dossier à la racine du serveur
 * dossier-principal
 *     |_ dossier-images-galerie-1
 *			|_ 99x99
 *     |_ dossier-images-galerie-2
 *			|_ 99x99
 *     |_ dossier-images-galerie-3
 *			|_ 99x99
 *     ...
 */
function galerie($args = '') {
	$default = array(
		'racine' => 'images',
		'dim_img' => 70, /* dimension miniature height = width */
		// 'nbre_col' => 'auto-fit', /* auto-fit ou nombre colonnes */
		'space_img' => 1, /* grid-gap */
		'nbre_img' => '',
		'img_ext' => 'jpg,png', /* extensions séparées par un virgule */
		'center' => 1, /* centrage galerie ; justify-content: center */
		'num_galerie' => 1, /* si plusieures galeries dans la page */
		'fb_name_bottom' => 0,
		'fb_new_window' => 0,
		'fb_img_nav' => 1,
		'fb_num_img' => 1, /* Image x de x */
		'fb_infos' => 0,
		'caption' => 0,
		'class' => '',
		'floatbox' => 0,
		'new_window' => 1,
		'debug' => 0, /* fonction test */
		'excluded' => '',
		'corner_img' => '',
		'title' => 0, /* title du <a>, s'affiche alors aussi dans floatbox au dessus de l'image agrandie */
				);
	if ($args != '') {
		if ( is_string( $args ) ) {parse_str($args, $tbl_args);}
		else {$tbl_args = $args;}
	$new = array_merge ($default, $tbl_args);
	extract( $new, EXTR_SKIP );
	}
	else {
	extract( $default, EXTR_SKIP );
	}
	// test($new, 't=$new&l='.basename(__FILE__).':'.__LINE__.' ');
// **********************************************
$tbl_excluded = explode(',', $excluded);
$html = '';
	// -----
	$url_folder_images = '../../'.$racine.'/';
	$path_folder_images = _NW_ROOT_.'/'.$racine.'/';
	// *****
	$img_ext = explode(',', $img_ext);
	// si folder non spécifié dans les paramètres du shortcode ou de la fonction
	if (!isset($folder)) {
		$html .= '<p style="color: #cc0000;">'.ICON_WARNING.MSG_ERREUR_AFFICHAGE_GALERIE.MSG_FOLDER_MISSING.'</p>';
		return $html;
	}
	// *****
	// dossier images originales
	$path_image = $path_folder_images.$folder.'/';
	$url_image = $url_folder_images.$folder.'/';
	// dossier images small
	$folder_images_small = $dim_img.'x'.$dim_img;
	$path_image_small = $path_folder_images.$folder.'/'.$folder_images_small.'/';
	$url_image_small = $url_folder_images.$folder.'/'.$folder_images_small.'/';;
	// -----
	if ($debug) {
		test($path_folder_images, 't=$path_folder_images&l='.basename(__FILE__).':'.__LINE__.' ');
		test($url_folder_images, 't=$url_folder_images&l='.basename(__FILE__).':'.__LINE__.' ');
		test($path_image, 't=$path_image&l='.basename(__FILE__).':'.__LINE__.' ');
		test($url_image, 't=$url_image&l='.basename(__FILE__).':'.__LINE__.' ');
		test($path_image_small, 't=$path_image_small&l='.basename(__FILE__).':'.__LINE__.' ');
		test($url_image_small, 't=$url_image_small&l='.basename(__FILE__).':'.__LINE__.' ');
	}
// -----
	// config messages d'erreur
	// pas de miniatures image_99x99.ext
	$error_galerie[2] = '<p style="color: #cc0000;">'.ICON_WARNING.
	sprintf(MSG_ERREUR_AFFICHAGE_GALERIE, $folder).
	sprintf(MSG_NO_THUMBNAILS_TO_DISPLAY_2, $racine.'/'.$folder.'/'.$folder_images_small).'</p>';
	// pas de dossier racine
	$error_galerie[3] = '<p style="color: #cc0000;">'.ICON_WARNING.sprintf(MSG_ERREUR_AFFICHAGE_GALERIE.MSG_PATH_NOT_EXIST, $racine).'</p>';
	// pas de dossier $folder
	$error_galerie[5] = '<p style="color: #cc0000;">'.ICON_WARNING.sprintf(MSG_ERREUR_AFFICHAGE_GALERIE.MSG_PATH_NOT_EXIST, $racine.'/'.$folder).'</p>';
	// paramètre fb_infos=1 mais fichier infos.php absent
	$error_galerie[6] = '<p style="color: #cc0000;">'.ICON_WARNING.sprintf(MSG_NO_FILE_INFOS, $folder).'</p>';
	// *****
	if (!file_exists($path_folder_images)) {
		$html .= $error_galerie[3]; // pas de dossier racine
		return $html;
	}
	elseif (!file_exists($path_folder_images.$folder)) {
			$html .= $error_galerie[5]; // pas de dossier racine/$folder
			return $html;
		}
	elseif (!file_exists($path_folder_images.$folder.'/'.$folder_images_small)) {
		$html .= '<p style="color: #cc0000;">'.ICON_WARNING.MSG_ERREUR_AFFICHAGE_GALERIE.
		sprintf(MSG_FOLDER_SMALL_MISSING, $folder.'/'.$folder_images_small).'</p>';
		return $html;
	} else {
		$tbl_img = searchExtFolder($path_image_small, $img_ext, $nbre_img, $tbl_excluded, $dim_img);
			// -----
			sort($tbl_img);
			$nbre_fic = count($tbl_img);
			if ($nbre_fic == 0) {
				$html .= $error_galerie[2]; // pas de minatures
				return $html;
			}
	}
	if ($debug) test($tbl_img, 'h=150&t=$tbl_img&l='.basename(__FILE__).':'.__LINE__.' ');
	if ($fb_infos) {
		if (file_exists($path_folder_images.$folder.'/infos.php'))
			require($path_folder_images.$folder.'/infos.php');
		else {
			$html .= $error_galerie[6]; // pas de fichier infos.php dans le dossier de la galerie
			$fb_infos = 0;
		}
	}
	// *****
	$dim_box = $dim_img;
	// *****
	// if ($nbre_col == 0 && $nbre_col != 'auto-fit') {$nbre_col = 1;}
	if ($space_img < 0) {$space_img = 0;}
	// *********************
	// générer le css inline
	$style_galerie_grid_container = '';
	$style_galerie_grid_container .= 'style="';
	$style_galerie_grid_container .= 'grid-template-columns: repeat(auto-fit, minmax('.$dim_box.'px, '.$dim_box.'px));';
	$style_galerie_grid_container .= 'grid-gap: '.$space_img.'px;';
	if ($center) $style_galerie_grid_container .='justify-content: center;';
	$style_galerie_grid_container .= '"';
	// test($style_galerie_grid_container, 't=$style_galerie_grid_container&l='.basename(__FILE__).':'.__LINE__.' ');
	// -----
	$style_galerie_box = '';
	$style_galerie_box .= 'style="';
	$style_galerie_box .= 'width: '.$dim_box.'px;';
	if ($caption == 0) {
		$style_galerie_box .= 'height: '.$dim_box.'px;';
	}
	$style_galerie_box .= '"';
	// test($style_galerie_box, 't=$style_galerie_box&l='.basename(__FILE__).':'.__LINE__.' ');
	// -----
	$style_galerie_box_img = '';
	if (!empty($corner_img)) {
		$style_galerie_box_img .= 'style="';
		$style_galerie_box_img .= 'border-radius: '.$corner_img.'px;';
		$style_galerie_box_img .= '"';
	}
	// test($style_galerie_box_img, 't=$style_galerie_box_img&l='.basename(__FILE__).':'.__LINE__.' ');
	// *****
	$tbl_class = array();
	if (!empty($class)) $tbl_class[] = $class;
	// eventuellement on rajoute class ici
	// $tbl_class[] = 'class-dans-function';
	if ($fb_img_nav) {
		$tbl_class[] = 'floatbox';
		$group = 'group:galerie'.$num_galerie;
	}
	else {
		$group = '';
	}
	// *****
	$tbl_class[] = 'galerie-grid-container-'.$num_galerie;
	$html_class = (empty($tbl_class)) ? '' : 'class="'.implode(' ', $tbl_class).'"';
	$data_fb_options = (empty($group)) ? '' : 'data-fb-options="'.$group.'"';
	$attr_div = array($html_class, $data_fb_options, $style_galerie_grid_container);
	$html_div = '';
	$html_div .= '<div';
	foreach ($attr_div as $attr) {
        $space = (empty($attr)) ? '' : ' ';
        $html_div .= $space.$attr;
    }
	$html_div .= '>'."\n";
	// $html .= test('<span style="white-space: pre-wrap;">'.htmlspecialchars($html_div).'</span>', 't=$html_div&echo=0');
	$html .= $html_div;
	// *****
	foreach ($tbl_img as $v) {
		// *****
		$html .= '<div '.$style_galerie_box.' class="galerie-box-'.$num_galerie.'">'."\n";
		// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
		// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
		// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
		$attr_fb_options = array();
		if ($fb_new_window) {
			$attr_fb_options[] = 'closeOnNewWindow:'.$fb_new_window;
			$attr_fb_options[] = 'showNewWindow:'.$fb_new_window;
		}
		if ($fb_infos) {
			if (isset($infos[removeSmall($v, $dim_img)]['desc'])) {
				$attr_fb_options[] = 'caption2:&#96;'.$infos[removeSmall($v, $dim_img)]['desc'].'&#96;';
			}
		}
		switch ($fb_name_bottom) {
			case 1:
				$attr_fb_options[] = 'caption:&#96;'.pathinfo(removeSmall($v, $dim_img), PATHINFO_FILENAME).'&#96;';
			break;
			case 2:
				$eeex = pathinfo($v, PATHINFO_EXTENSION);
				$iiii = pathinfo(removeSmall($v, $dim_img), PATHINFO_FILENAME).'.'.$eeex;
				$attr_fb_options[] = 'caption:&#96;'.$iiii.'&#96;';
			break;
		}
		$fb_num_img1 = ($fb_num_img) ? 'true' : 'false';
		$attr_fb_options[] = 'showItemNumber:'.$fb_num_img1;
		// -----
		if (count($attr_fb_options) != 0) {
			$html_fb_options = 'data-fb-options="';
			$html_fb_options .= implode(' ', $attr_fb_options);
			$html_fb_options .= '"';
			// test('<span style="white-space: pre-wrap;">'.htmlspecialchars($html_fb_options).'</span>', 't=$html_fb_options');
		}
		// -----
		$attr_img = array(
			'src="'.$url_image_small.$v.'"',
			'alt="'.pathinfo(removeSmall($v, $dim_img), PATHINFO_FILENAME).'"',
			$style_galerie_box_img
		);
		// -----
		$html_img = '<img';
		foreach ($attr_img as $attr) {
			$space = (empty($attr)) ? '' : ' ';
			$html_img .= $space.$attr;
		}
		$html_img .= '>';
		// test('<span style="white-space: pre-wrap;">'.htmlspecialchars($html_img).'</span>', 't=$html_img');
		// -----
		// ####################################
		// ajout 2022-03-15 19:36:59
		$use_floatbox = ($floatbox) ? '' : 'class="nofloatbox" ';
		$new_window = ($new_window) ? 'target="_blank"' : '';
		// ####################################
			$v1 = removeSmall($v, $dim_img);
			// test($v1, 't=$v1&l='.basename(__FILE__).':'.__LINE__.' ');
			// *****
			$title = ($title) ? 'title="'.pathinfo($v1, PATHINFO_FILENAME).'"' : '';
			$attr_a = array(
				'href="'.$url_image.$v1.'"',
				$title,
				$use_floatbox,
				$new_window,
			);
			$html_a = '<a ';
			if (count($attr_fb_options) != 0) {
				$html_a .= ' '.$html_fb_options;
			}
			foreach ($attr_a as $attr) {
				$space = (empty($attr)) ? '' : ' ';
				$html_a .= $space.$attr;
			}
			$html_a .= '>'."\n";
			$html_a .= $html_img."\n";
			$html_a .= '</a>'."\n";
			// test('<span style="white-space: pre-wrap;">'.htmlspecialchars($html_a).'</span>', 't=$html_a');
			$html .= $html_a;
		// ####################################
		// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
		// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
		// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
		// Ajout : 26/08/2026
		if ($caption == 1  && $fb_infos == 1) {
			// modification 03-09-2026 : erreur si pas de description pour une image ou si erreur dans nom image
			if (isset($infos[removeSmall($v, $dim_img)]['desc'])) {
				$html .= '<span class="miniature-caption">'.$infos[removeSmall($v, $dim_img)]['desc'].'</span>';
			}
		}
		$html .= '</div><!-- galerie-box-'.$num_galerie.' -->'."\n";
	} // end foreach ($tbl_img as $v)
	$html .= '</div><!-- galerie-grid-container-'.$num_galerie.' -->'."\n";
return $html;
} // end function galerie

function removeSmall($s, $d) {
	$small = sprintf(FORMAT_THUMBNAIL, $d, $d);
	$s1 = pathinfo($s, PATHINFO_FILENAME);
	$s1 = str_replace($small, '', $s);
	return $s1;
}
?>

Feuille de style

/**
 * styles généraux communs à toutes les galeries
 * www.nonoweb.net
 */
 
div[class*="galerie-grid-container-"] {
	display: grid;
	justify-items: center;
}

div[class*="galerie-box-"] {
	background: none;
	text-align: center;
	-moz-box-sizing: border-box;
	-webkit-box-sizing: border-box;
	box-sizing: border-box;
}

div[class*="galerie-box-"] img {}

Exemples d'intégration de galerie d'images

[galerie:folder=moon&floatbox=1&dim_img=48&fb_name_bottom=1&fb_new_window=1]

Exemple avec description sous miniature

[galerie:folder=nonoweb/simpleDBMS&dim_img=256&floatbox=1&space_img=10&fb_infos=1&class=galerie-simpledbms&fb_new_window=1&corner_img=10&caption=1&nbre_img=3]
simpleDBMS-01 Connexion
simpleDBMS-11 Sauvegarde SQL
simpleDBMS-21 SQL : Requête

Laisser un commentaire (Seuls le nom et le commentaire sont requis).
Les commentaires sont modérés avant publication.

 
Sélection smileys