tuto

Galerie d’images dynamique

Le but de ce tutoriel va être de reprendre le tutoriel « Galerie Snoupix Flip » réalisé en Jquery et d’en faire une galerie dynamique avec une petite interface d’administration pour gérer chaque photo. Au programme, vous allez essentiellement travailler avec l’upload d’image en PHP, l’insertion, la sélection et la suppression de données dans une table MySQL. C’est parti… Démo Source Etape 1: Création de la table SQL Chaque image …

 

Le but de ce tutoriel va être de reprendre le tutoriel « Galerie Snoupix Flip » réalisé en Jquery et d’en faire une galerie dynamique avec une petite interface d’administration pour gérer chaque photo. Au programme, vous allez essentiellement travailler avec l’upload d’image en PHP, l’insertion, la sélection et la suppression de données dans une table MySQL. C’est parti…

Etape 1: Création de la table SQL

Chaque image aura donc comme information: un identifiant unique, un nom et le lien de son image sur le serveur. Ces informations seront inscrites dans la base de données, tandis que l’image et sa miniature seront dans un dossier « images » de votre serveur. Voici le script SQL que vous pouvez éxécuter directement dans PHPMyAdmin (généralement PhpMyadmin se trouve à cette adresse: http://localhost/phpmyadmin/, si vous travaillez en local)

CREATE TABLE `galerie`.`images` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`nom` VARCHAR( 100 ) NOT NULL ,
`lienimage` VARCHAR( 100 ) NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM

La base de données s’appelle donc « galerie », et la table se nomme « images ». L’identifiant (‘id’) créé est unique et s’incrémentera automatiquement lors de chaque ajout d’images.

Etape 2: La page d’administration

Tout d’abord spécifions l’arborescence de nos fichiers. J’ai crée pour cette petite application 3 dossiers:

  • css : reprend tous les fichiers de mise en page.
  • js : tous les fichiers Javascript qui serviront dans la dernière étape du tuto.
  • images: contient évidemment toutes les images ainsi qu’un dossier miniatures.

Nous allons créer l’ossature de notre page HTML (« admin.php ») situé à la racine de notre projet en utilisant pour l’instant que de l’HTML avec un peu de CSS, histoire de rendre les choses agréables à regarder.

<!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" xml:lang="fr" lang="fr" dir="ltr">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

		<!-- CSS -->
<link rel="stylesheet" href="css/admin.css" _mce_href="css/admin.css" type="text/css" media="screen, projection" />
	</head>
	<body>
<form method="post" action="admin.php" enctype="multipart/form-data">
<fieldset>
<legend>Ajout d'une image</legend>

				<label for="nom">Nom</label>
<input type="text" id="nom" name="nom"/>
				<label for="image1">Image</label>
<input type="file" id="image1" name="image1"/>
				<label for="image2">Miniature</label>
<input type="file" id="image2" name="image2"/>
				<button type="submit">Uploader</button>
			</fieldset>
</form>
<table summary="Liste des images de la galerie">
<caption>Liste des images</caption>
<tr>
<th>Id</th>
<th>Nom</th>
<th>Supprimer</th>
</tr>
</table>

	</body>
</html>

Voilà pour l’HTML, vous pouvez noter dans la balise form, l’attribut enctype dont la valeur est « multipart/form-data » : Cela signifie que le formulaire encode les données de votre formulaire, cela est indispensable pour uploader des images.
Sinon Le tableau est pour l’instant vide car il sera remplit dynamiquement en PHP/SQL par la suite. Voici le fichier CSS (« css/admin.css »), histoire de rendre ce tuto moins monotone ^^.

form{
	width:500px;
	margin:auto;
	background-color:#e5e5e5;
	border-radius:1em; /*Trop cool pour IE :)  */
	-moz-border-radius:1em; /*Trop cool pour IE :)  */
}
form *{
	font-size:1.0em;
	font-family:georgia;
}
form fieldset{
	border:none;
}

form legend{
	font-size:2em;
	color:#777;
	margin-top:0.3em;
}
form label{
	display:block;
	float:left;
	width:150px;
	text-align:right;
}
form input, form select, form textarea{
	width:300px;
	margin-bottom: 1em;
	margin-left:0.5em;
}
form button{
	position:relative;
	left:160px;
}

table{
width:50%;
margin:auto;
}
table caption{
font-size:2em;
color:#777;
}
table th{
background-color:#ddd;
border:none;
}

Etape 3: Ajouter des images

Maintenant, attaquons le coeur de notre problème et commencons par traiter les données de notre formulaire. Le script PHP se trouvera au tout début de notre page « admin.php », tout simplement parce que l’on a spécifié cette page dans l’attribut action du formulaire. Sachez que pour récupérer une image, il existe une variable appelée « superglobale » $_FILES['nomdevotreinput'] qui fonctionne de la même manière qu’une variable de type $_POST ou $_GET. Maintenant voyons le code avant de rentrer dans les détails:

<?php
include('params.inc.php');
if(!empty($_POST['nom'])){
	$erreurs = array(); //initialise un tableau d'erreurs au cas ou :)
	$nom = mysql_escape_string(trim($_POST['nom'])); //enleve les espaces de chaque côté de la variable
	$lienimage = '';
	$typesacceptes = array('image/jpeg','image/jpg','image/png','image/gif');
	//vérifie si les images existent et qu'elles sont au bon format
	if(!empty($_FILES['image1']['name']) &&
	!empty($_FILES['image2']['name']) &&
	in_array($_FILES['image1']['type'],$typesacceptes) &&
	in_array($_FILES['image2']['type'],$typesacceptes)
	){
		$lienimage = mysql_escape_string($_FILES['image1']['name']);
		copy($_FILES['image1']['tmp_name'],'images/'.$lienimage);
		copy($_FILES['image2']['tmp_name'],'images/miniatures/'.$lienimage);

		//connexion à la BDD
		$connect=mysql_connect(MYHOST,MYUSER,MYPASS) or die ('erreur de connexion');
		mysql_select_db(MYDB) or die ('erreur de connexion à la base');

		$requeteinsert = 'INSERT INTO images(nom,lienimage) VALUES(\''.$nom.'\',\''.$lienimage.'\')';
		$result = mysql_query($requeteinsert,$connect);
		mysql_close($connect);
	}
	else{
		$erreurs[] = 'Veuillez uploader une image valide (format jpg, png ou gif)!';
	}
}
?>

Vous pouvez noter l’inclusion d’un script PHP (« params.inc.php »), au tout début du programme, celui-ci possède les renseignements pour la connexion à la Base de données et contiendra probablement ceci si vous travaillez en local:

<?php
define("MYHOST","localhost");
define("MYUSER","root");
define("MYPASS","");
define("MYDB","galerie");
?>

Dans un premier temps, nous vérifions si la variable $_POST['nom'] existe et n’est pas vide, auquel cas nous éxécutons la suite du script sinon rien ne se passe. Ensuite nous créons une variable $nom qui reprend la variable du formulaire en la nettoyant un peu à l’aide des fonctions trim() qui enlève les espaces au début et en fin de variable et de la fonction mysql_escape_string() qui assure un minimum de sécurité lors de l’insertion de la variable dans la requête SQL. Comme je l’ai dit auparavant, pour récupérer un fichier d’un formulaire la variable $_FILES est indispensable. Celle_ci est en fait comme $_POST, un tableau associatif avec comme clé la valeur de l’attribut « name » de notre formulaire (ici « image1″ par exemple). Cette variable est assez intéressante car elle nous propose aussi plusieurs propriétés de l’élément uploadé disponible de cette façon:

 

  • $_FILES['image1']['name'] : nom de votre image.
  • $_FILES['image1']['size'] : taille de votre fichier (en bits).
  • $_FILES['image1']['tmp_name'] : Chemin temporaire de votre fichier uploadé.
  • $_FILES['image1']['error'] : Equivaut à 0 si tout se passe bien, sinon un numéro d’erreur est attribué (taille trop grande, transfert échoué,etc…).
  • $_FILES['image1']['type'] : Type MIME de votre fichier.

Par la suite, on vérifie donc les images uploadées (si elles ont un nom et un type valide). Pour la validation des types j’utilise la fonction in_array() qui renvoit true si la chaîne passée en premier paramètre correspond à un élément du tableau.

La fonction copy(), comme son nom l’indique copie juste un fichier, en indiquant en 1er paramètre le fichier source, et en 2ème paramètre, la destination. Pour finir on éxécute une requête SQL de type INSERT INTO, avec comme valeurs le nom de l’image et son lien.

Comme vous avez pu le voir, j’ai crée un tableau d’erreurs qui se remplit si le formulaire est mal complété, j’utilise un tableau et non une chaîne, par simple habitude, ici une chaîne aurait suffit. Mais s’il existe plusieurs types d’erreurs, il est intéressant de pouvoir les avoir sous forme de tableau.

Pour afficher ce tableau correctement je vous propose de placer ce code juste avant le formulaire:

<?php
		if(!empty($erreurs)){
			echo '
<div class="error">

Erreurs rencontrées
<ul>';
			foreach($erreurs as $erreur){
				echo '
<li>'.$erreur.'</li>

';
			}
			echo '</ul>
</div>

';
		}
?>

Et avec un peu de CSS pour que tout soit joli:

.error,.success{
	width:50%;
	padding:0.3em;
	margin:0.3em auto;
}
.error{
	color:#8a1f11;
	background-color:#fbe3e4;
	border:2px solid #8a1f11;
}
.success{
	border:2px solid #1f9b15;
	color:#1f9b15;
	background-color:#cefcd4;
}

Vous pouvez dorénavant uploader des images sur votre serveur. La prochaine étape consistera à pouvoir les voir et les supprimer à partir de votre tableau.

 

Etape 4: Gérer ses images

Notre but est maintenant de remplir le tableau, il faudra donc placer le prochain script juste après la balise fermante

 

<?php
			$connect=mysql_connect(MYHOST,MYUSER,MYPASS) or die ('erreur de connexion');
			mysql_select_db(MYDB) or die ('erreur de connexion à la base');

			$requeteselect = 'SELECT id,lienimage,nom FROM images';
			$result = mysql_query($requeteselect, $connect);
			while($image_courante = mysql_fetch_array($result,MYSQL_ASSOC)){
				echo '
<tr>
<td>'.$image_courante['id'].'</td>
<td>'.stripslashes($image_courante['nom']).'</td>
<td><a href="admin.php?sup='.$image_courante['id'].'" _mce_href="admin.php?sup='.$image_courante['id'].'">Supprimer</a></td>
</tr>

';
                                }
?>

Ce script n’est pas très compliqué et reprend beaucoup de fonctions déjà utilisées auparavant. Pour afficher toutes les lignes de notre requête, nous avons besoin de réaliser une boucle while qui éxécute la fonction mysql_fetch_array(). Celle-ci permet de séléctionner les données d’une ligne et de les insérer dans un tableau jusqu’à ce qu’il n’y en ai plus aucune. A noter aussi la fonction stripslashes() sur le nom de l’image, en fait cette fonction permet de supprimer les antislashs que la fonction mysql_escape_string() aura placé devant les caractères tels que  » ou ‘ .

 

Pour la colonne suppression, j’utilise une URL de type « GET » qui prend en paramètre l’identifiant de l’image qu’on veut supprimer. Cela nécessite un nouveau script à placer juste avant l’affichage des lignes. Si on le place après il faudrait en fait raffraîchir la page pour ne plus voir la ligne supprimée, ce qui n’est pas très judicieux. Voici le code:

if(!empty($_GET['sup']) && is_numeric($_GET['sup'])){
				$requeteselect = 'SELECT lienimage FROM images WHERE id=\''.mysql_escape_string($_GET['sup']).'\'';
				$result = mysql_query($requeteselect, $connect);
				$image_courante = mysql_fetch_array($result,MYSQL_ASSOC);
				unlink('images/'.$image_courante['lienimage']);
				unlink('images/miniatures/'.$image_courante['lienimage']);

				$requetesup = 'DELETE FROM images WHERE id=\''.mysql_escape_string($_GET['sup']).'\'';
				$result = mysql_query($requetesup, $connect);
}

Ce bout de code permet donc de supprimer dans la base de données mais aussi de supprimer les images associées sur votre serveur! La fonction qui permet de supprimer est unlink() qui prend pour paramètre l’url relatif de votre fichier à supprimer.

 

administration galerie

L’administration est enfin terminée, on peut passer maintenant à la galerie proprement dite. Si vous n’avez pas fait le tuto sur la galerie Snoupix Flip, je vous conseille d’aller y jeter un oeil puisque je reprends exactement le même code.

Etape 5: La galerie

J’ai tout simplement repris le code source disponible dans le tuto. En décompressant l’archive dans le dossier dans lequel nous travaillons actuellement (inutile par contre de décompresser le dossier images).

La première étape va consister à renommer l’extension de snoupixFlip.htm en snoupixFlip.php. Vous vous retrouverez donc avec cette page:

<!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" xml:lang="fr" lang="fr">
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" _mce_href="style.css" media="screen"/>
        <mce:script type="text/javascript" _mce_src="js/jquery-1.3.1.js"></mce:script>
        <mce:script type="text/javascript" _mce_src="js/jquery-ui-personalized-1.6rc2.packed.js"></mce:script>
        <mce:script type="text/javascript" _mce_src="js/jquery.flip.js"></mce:script>
        <mce:script type="text/javascript" _mce_src="js/codeFlip.js"></mce:script>
</head>
<body>
<div id="header">
                <img src="images/Snoupix_Flip.jpg" _mce_src="images/Snoupix_Flip.jpg" alt="Snoupix Flip" />
        </div>
<div id="conteneur">
<div id="principale">
<div id="flipBox">
<div class="grande_image">
                                        <img src="images/TheCube.jpg" _mce_src="images/TheCube.jpg" alt="Snoupix Flip"/><span>The Cube HDR</span>
                                </div>
</div>
<div class="miniatures">
                                <a class="flipBT" href="#" _mce_href="#" title="TheCube HDR">
                                        <img src="images/TheCube_s.jpg" _mce_src="images/TheCube_s.jpg" class="chemin" alt="images/TheCube.jpg"/>
                                </a>
                                <a class="flipBT" href="#" _mce_href="#" title="Audi R8 HDR">
                                        <img src="images/R8_s.jpg" _mce_src="images/R8_s.jpg" class="chemin" alt="images/R8.jpg"/>
                                </a>
                                <a class="flipBT" href="#" _mce_href="#"   title="Subaru HDR">
                                        <img src="images/subaru_s.jpg" _mce_src="images/subaru_s.jpg" class="chemin" alt="images/subaru.jpg"/>
                                </a>
                                <a class="flipBT" href="#" _mce_href="#"  title="Bazzar HDR">
                                        <img src="images/Bazzar_s.jpg" _mce_src="images/Bazzar_s.jpg" class="chemin" alt="images/Bazzar.jpg"/>
                                </a>
                                <a class="flipBT" href="#" _mce_href="#"  title="BlueOnFire HDR">
                                        <img src="images/BlueOnFire_s.jpg" _mce_src="images/BlueOnFire_s.jpg" class="chemin" alt="images/BlueOnFire.jpg"/>
                                </a>
                                <a class="flipBT" href="#" _mce_href="#"  title="toyRoom HDR">
                                        <img src="images/ToyRoom_s.jpg" _mce_src="images/ToyRoom_s.jpg" class="chemin" alt="images/ToyRoom.jpg"/>
                                </a>
                                <a class="flipBT" href="#" _mce_href="#"  title="Trunk HDR">
                                        <img src="images/Trunk_s.jpg" _mce_src="images/Trunk_s.jpg" class="chemin" alt="images/Trunk.jpg"/>
                                </a>
                                <a class="flipBT" href="#" _mce_href="#"  title="WinterTrain HDR">
                                        <img src="images/WinterTrain_s.jpg" _mce_src="images/WinterTrain_s.jpg" class="chemin" alt="images/WinterTrain.jpg"/>
                                </a>
                        </div>
</div>
</div>

</body>
</html>

Les différentes miniatures ne nous intéressent plus dorénavant puisque nous allons tout afficher dynamiquement, ce qui nous donne maintenant ceci:

<!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" xml:lang="fr" lang="fr">
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" _mce_href="style.css" media="screen"/>
        <mce:script type="text/javascript" _mce_src="js/jquery-1.3.1.js"></mce:script>
        <mce:script type="text/javascript" _mce_src="js/jquery-ui-personalized-1.6rc2.packed.js"></mce:script>
        <mce:script type="text/javascript" _mce_src="js/jquery.flip.js"></mce:script>
        <mce:script type="text/javascript" _mce_src="js/codeFlip.js"></mce:script>
</head>
<body>
<div id="header">
<h1>Galerie Dynamique</h1>
</div>
<div id="conteneur">
<div id="principale">
<div id="flipBox">
<div class="grande_image">
                                    <?php
							//remplir par la premiere image
						 ?>
                                </div>
</div>
<div class="miniatures">
                               <?php
							//remplir par toutes les miniatures
					?>
                        </div>
</div>
</div>

</body>
</html>

Et enfin voila la page avec le code PHP:

<div id="flipBox">
<div class="grande_image">
 	<?php
 	include('params.inc.php');
 	$connect=mysql_connect(MYHOST,MYUSER,MYPASS) or die ('erreur de connexion');
 	mysql_select_db(MYDB) or die ('erreur de connexion à la base');
 	$requeteselect = 'SELECT id,lienimage,nom FROM images';
 	$result = mysql_query($requeteselect, $connect);
 	$tableau = array();
 	$i = 0;
 	while($image_courante = mysql_fetch_array($result,MYSQL_ASSOC)){
 		//on met toutes les infos dans un tableau
 		$tableau[$image_courante['id']]['nom'] = $image_courante['nom'];
 		$tableau[$image_courante['id']]['lienimage'] = $image_courante['lienimage'];
 		if($i == 0){ //si il s'agit de la première image on l'affiche
 			echo '<img src="images/'.$tableau[$image_courante['id']]['lienimage'].'" _mce_src="images/'.$tableau[$image_courante['id']]['lienimage'].'"
 alt="'.stripslashes($tableau[$image_courante['id']]['nom']).'"/>
 <span>'.stripslashes($tableau[$image_courante['id']]['nom']).'</span>';
 		}
 		++$i;
 	}
 	mysql_close($connect);
 	?>
 	</div>
</div>
<div class="miniatures">
	<?php
	foreach($tableau as $image){
		echo '<a class="flipBT" href="#" _mce_href="#"  title="'.stripslashes($image['nom']).'">
			<img src="images/miniatures/'.$image['lienimage'].'" _mce_src="images/miniatures/'.$image['lienimage'].'" class="chemin" alt="images/'.$image['lienimage'].'"/>
			</a>';
	}
	?>
</div>

Ce code n’est pas non plus très difficile à appréhender si jusque là vous avez bien tout assimilé. Je remplis en fait un tableau multidimensionnel ($tableau) qui contiendra mes 2 informations essentielles, le nom et le chemin de l’image et dont leurs clés est l’identifiant de l’image.

 

Ensuite, afin de lister les miniatures, nous utilisons la fonction foreach() qui est une sorte de boucle qui parcourt le tableau, identifiant par identifiant.

Ce tutoriel touche à sa fin, j’espère qu’il vous aura appris certains trucs et qu’il pourra vous donner certaines idées. En tout cas le script final est biensûr à améliorer sur divers points (recadrage dynamique de la miniature, Modification des noms d’image, etc).

68 commentaires

S'abonner au RSS des commentaires
  1. enzo
    Posté le 20/10/2011 à 1h18

    Le tuto est bon dans l’ensemble mais pourquoi ne pas avoir utilisé PDO .

    Si j’ai le temps je le referais posterais les source ici mais avec les driver PDO pour les requete SQL

  2. Lacfab
    Posté le 18/09/2011 à 8h51

    La démo ne fonctionne ni sous Firefox, ni sous Safari … je ne vais pas plus loin dans la lecture du tuto … dommage !

  3. Jean
    Posté le 28/07/2011 à 11h13

    Bonjour,
    Etape 4: Gérer ses images…
    prochain script juste après la balise fermante ?
    c’est où?
    Puis, Cela nécessite un nouveau script à placer juste avant l’affichage des lignes ?
    je n’ai pu aller plus loin!
    Merci de préciser.

  4. Jean
    Posté le 28/07/2011 à 11h05

    Bonjour,
    Débutant en php-mysql, j’ai essayé de comprendre les scripts…n’ayant pas une vue d’ensemble, je suis perdu dans les insertions de code php dans admin.php à partir des ‘gérer ses images’. Bref je ne puis tester le fonctionnement de la galerie.
    Merci pour le tuto.

  5. Stoff
    Posté le 05/03/2011 à 12h38

    Bonjour, ce tuto me semble intéressant et relativement facile pour le béotien que je suis, peut-on afficher plusieurs galeries sur une même page ? Disons 5 galeries par page avec une pagination…j’essaie de réaliser un site perso (graphiste) et j’aimerai vraiment utiliser le php et mysql pour gérer dynamiquement l’affichage de mon "travail", soit une galerie que décris ce tuto pour chacune de mes réalisations (comme il s’agit presque toujours de series d’images, j’aimerai des galeries avec "prec" "suiv", et transition de type fade ou slide…) merci par avance pour votre aide

  6. TRUNCKS
    Posté le 06/01/2011 à 1h10

    Bonjour à vous,

    J’ai essayé de faire la galerie comme dans le tuto.

    Après plusieurs heures de bidouillages ( je suis nouveau en php ), j’ai quelques petits soucis.

    Pour l’upload d’image, pas de soucis particulier, sauf que si j’actualise ma page, tout tombe en rideau ( la dernière se dédouble )

    Mais le plus gros soucis, c’est la partie ou les images s’affichent, la grande image s’affiche correctement mais la miniature fait n’importe quoi.

    Déjà elle chevauche la grande, elles se mettent les unes en dessous des autres ( au lieu de côte à côte ) et je n’arrive pas du tout à la redimensionner automatiquement quand je l’upload, elle aura la taille de l’image par défaut.

    Vous pouvez aider un humble débutant ?

  7. Gugul
    Posté le 10/06/2010 à 16h49

    Bonjour !
    Aucun souci de mon coté si ce n’est une petite erreur que me signale firebug à chaque clic sur une miniature ( ce serait du au href="#" du <a> de la div miniature apparemment, m’enfin).

    Par contre je me demandais, est-t’il possible de charger la grande photo sans avoir à recharger la page ( ce qui la remonte au header, gênant quand la galerie se situe assez bas dans le site).

    Merci d’avance !

  8. Stephane
    Posté le 17/05/2010 à 21h31

    Merci pour ta solution.

Laisser un commentaire

Votre e-mail ne sera jamais publié ni communiqué. Les champs obligatoires sont indiqués par *

*
*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>