Page 1 sur 1

Double exécution d'une requête PDO

Posté : 06 févr. 2010, 14:44
par visualight
Bonjour,

Je me demandais comment je pourrais réaliser une double exécution d'une requête PDO sans avoir a retaper ma requête entière.
Voici comment je faisais avec de simples requêtes QUERY.
Comment puis je faire la même chose en PDO ?
// On exécute une première fois la reqête afin d'afficher les résultats pour l'affichage des miniatures d'images
$req="SELECT * FROM $CfgTableObjects INNER JOIN $CfgTableMain ON ($CfgTableObjects.gallery_id=$CfgTableMain.gallery_id) 
WHERE $CfgTableObjects.gallery_id='$galid' AND $CfgTableObjects.object_type='photo'";

$res=mysql_query($req) or die(mysql_error());

while ($row = mysql_fetch_array ($res)) {
... 

(UN PEU PLUS LOIN DANS LE MEME FICHIER)...

// Maintenant on va réexécuter la requête pour le watermak des images

if (isset ($_GET['intitle']) AND isset ($_GET['file'])) {
...
// CONDITION WATERMARK - START
// On effectue une duplication de la requete pour l'obtention de la condition watermark 
// (nécessaire sinon cela rentre en conflit avec les miniatures et du coup la miniature n°1 disparait de la liste des images)

$res_wtmrk=mysql_query($req) or die(mysql_error());

// On va chercher le champ "watermark_active"
$row = mysql_fetch_array ($res_wtmrk);
...
Vous remarquerez donc que je ne duplique pas ma requête mais je la réexécute sous l'égide d'une autre variable ($res_wtmrk).
En PDO, j'ai essayé pas mal de truc pour ne pas avoir a dupliquer toute la requête, mais rien n'y fait !
// On exécute la requete une première fois pour l'affichage des miniatures et autres modules
$req = $connexion->prepare ("SELECT * FROM $CfgTableObjects INNER JOIN $CfgTableMain ON ($CfgTableObjects.gallery_id=$CfgTableMain.gallery_id) 
WHERE $CfgTableObjects.gallery_id=:galid AND $CfgTableObjects.object_type=:photo");

$req->execute(array (':galid' => $galid, ':photo' => 'photo'));

(UN PEU PLUS LOIN DANS LE MEME FICHIER) ...

// LA seule solution que j'ai trouvé est de dupliquer toute la requête !

// CONDITION WATERMARK - START
// On effectue une duplication de la requete pour l'obtention de la condition watermark
//$res_wtmrk = $req->execute(array (':galid' => $galid, ':photo' => 'photo'));

// Malheureusement je duplique tout
$req_wtmrk = $connexion->prepare ("SELECT * FROM $CfgTableObjects INNER JOIN $CfgTableMain ON ($CfgTableObjects.gallery_id=$CfgTableMain.gallery_id) 
WHERE $CfgTableObjects.gallery_id=:galid AND $CfgTableObjects.object_type=:photo");
	 
$req_wtmrk->execute(array (':galid' => $galid, ':photo' => 'photo'));

 // On va chercher le champ "watermark_active"
 $row = $req_wtmrk->fetch(PDO::FETCH_ASSOC);
...

Avez-vous compris ce que je tente de faire ?
Pouvez-vous m'aider?

Merci,
raph

Re: Double exécution d'une requête PDO

Posté : 06 févr. 2010, 14:58
par Ryle
Et qu'est ce qui t'empêche de refaire un $req->execute() pour l'exécuter une seconde fois et recommencer avec les fetch ?

Cependant, plutôt que d'exécuter deux fois ta requête, pourquoi ne pas adapter ton code pour stocker les données récupérées afin de les utiliser tant que tu veux par la suite ? :)

Re: Double exécution d'une requête PDO

Posté : 06 févr. 2010, 15:23
par visualight
Bonjour,

Je ne puis malheureusement exécuter ma requete une deuxième fois comme ceci car cela rentre apparemment en conflit avec le reste et du coup sur le nombre de miniatures affichées (exemple 5) la première disparait lorsque je clique dessus.
$req->execute(array (':galid' => $galid, ':photo' => 'photo'));

J'ai beau chercher, je ne vois pas ou est mon problème.
Comme plusieurs têtes valent mieux qu'une, je poste le code complet de ma page avec des commentaires.

Peux être pouvez vous alors me dire ce qui cloche, ce que je dois modifier et où je dois le faire ?

Explications de fonctionnement :

1. lorsqu'on visite une galerie, les miniatures apparaissent correctement et en ombre exact.
L'affichage de la galerie se fait par défaut par le biais de : if (!isset ($_GET['action']) OR empty ($_GET['action']) OR $_GET['action'] == 'mini') {

2. lorsque je clique sur une miniature et si je ne duplique pas la requete au niveau du watermark : if (isset ($_GET['intitle']) AND isset ($_GET['file'])) {, une miniature disparait (en l'occurrence la première miniature).

3. Si je duplique la requête sous un autre nom de variable tout fonctionne correctement.
exemple :
$req_wtmrk = $connexion->prepare ("SELECT * FROM $CfgTableObjects INNER JOIN $CfgTableMain ON ($CfgTableObjects.gallery_id=$CfgTableMain.gallery_id) 
WHERE $CfgTableObjects.gallery_id=:galid AND $CfgTableObjects.object_type=:photo");
	 
$req_wtmrk->execute(array (':galid' => $galid, ':photo' => 'photo'));
Je me doute que mon code n'est certainement pas des plus déontologique mais il est fonctionnel.
Peux être pourrez vous me dire ce que je dois modifier pour qu'il soit un peu plus déontologique et fonctionnel ?
<?php

	 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	 <html xmlns="http://www.w3.org/1999/xhtml">
	 <head>
	 <link href="styles/photoweb_style.css" rel="stylesheet" type="text/css" />
	 </head><body>';
	
	// On teste la véracité de l'ID de la galerie
	if (!is_numeric($_GET['galid'])) {
	 echo ' Erreur : L\'id de la galerie n\'existe pas ou n\'est pas numérique';
	} else {

	 // On inclus le fichier de configuration
	 require_once ('.dirsys/conf/fichierconf.conf.php');

	 // Connection à la base de donnée
	 include ('.dirsys/lib/dbCon.lib.php');
	 
	 // On attribue l'ID de la galerie
	 $galid=$_GET['galid'];
	 
	 // On exécute une première fois la reqête pour l'affichage de résultats un peu plus loin (modules : $_GET[action] = mini ET $_GET[action] = diapo)
	 $req = $connexion->prepare ("SELECT * FROM $CfgTableObjects INNER JOIN $CfgTableMain ON ($CfgTableObjects.gallery_id=$CfgTableMain.gallery_id) 
	 WHERE $CfgTableObjects.gallery_id=:galid AND $CfgTableObjects.object_type=:photo");
	 
	 $req->execute(array (':galid' => $galid, ':photo' => 'photo'));
	 
	 
	 // On affiche le titre de la galerie
	 echo '<div id="bannerGalleryDetailContainer">
	 <p class="bannerGalleryDetailTitle1">La galerie photo ...</p>
	 <p class="bannerGalleryDetailTools"><a href="'.$_SERVER['PHP_SELF'].'?galid='.$_GET['galid'].'" target="_self">Miniatures</a> | <a href="'.$_SERVER['PHP_SELF'].'?galid='.$_GET['galid'].'&action=diapo" target="_self">Diaporama</a></p>
	 </div>';

	 // Si le titre interne et le nom du fihier apparaissent dans le $_GET, on affiche la photo
		if (isset ($_GET['intitle']) AND isset ($_GET['file'])) {
		 $photo = $CfgDir_Gallery.'/'.$_GET['intitle'].'/'.$CfgDir_Photos.'/'.$CfgDir_Thumbs.'/'.$CfgDir_Thumbs_Medium.'/'.$_GET['file'];
		 $bigphoto = $CfgDir_Gallery.'/'.$_GET['intitle'].'/'.$CfgDir_Photos.'/'.$_GET['file'];

		 // CONDITION WATERMARK - START
		 // On effectue une duplication de la requete pour l'obtention de la condition watermark
		 // >>>>>>>>>> C'EST ICI QUE CA CLOCHE
		$req_wtmrk = $connexion->prepare ("SELECT * FROM $CfgTableObjects INNER JOIN $CfgTableMain ON ($CfgTableObjects.gallery_id=$CfgTableMain.gallery_id) 
		WHERE $CfgTableObjects.gallery_id=:galid AND $CfgTableObjects.object_type=:photo");
	 
		$req_wtmrk->execute(array (':galid' => $galid, ':photo' => 'photo'));

		 // On va chercher le champ "watermark_active"
		 $row = $req_wtmrk->fetch(PDO::FETCH_ASSOC);
		 $watermarkactif = $row['watermark_active'];
		 
		 // Affichage du détail de la photo miniature (image médium)
		 echo '<div id="galleryDetail_PixShow">';

			// Si le watermark est actif, on affiche la grande photo avec watermark (traitement du lien)
			if (empty ($watermarkactif) OR $watermarkactif == 'true') {
			 echo '<a href=wtmrk.php?photo='.$bigphoto.' target="_blank"><img src="'.$photo.'" alt="'.$_GET['file'].'" /></a></div>';
			 // Sinon, si le watermark est innactif (false), on affiche la grande photo sans watermark (traitement du lien)
			} elseif ($watermarkactif == 'false') {
			 echo '<a href='.$bigphoto.' target="_blank"><img src="'.$photo.'" alt="'.$_GET['file'].'" /></a></div>';
			} else {
			 // Sinon, si watermark est vide ou autre valeur que true ou false, on affiche l'image medium sans lien
			 echo '<img src="'.$photo.'" alt="'.$_GET['file'].'" /></div>';
			}
		 // CONDITION WATERMARK - END
		}

		// On teste si $_GET[action] est = à miniatures (si "action" est inexistant ou vide)
		if (!isset ($_GET['action']) OR empty ($_GET['action']) OR $_GET['action'] == 'mini') {

		 // On récupère les éléments nécessaires
			while ($row = $req->fetch(PDO::FETCH_ASSOC)) {
			
			 $filename = $row['object_filename'];
			 $int_title = $row['gallery_int_title'];
			 $phototitle = $row['object_title'];
			 $galid = $row['gallery_id'];

				// Si le nom de fichier est vide, on utilisera une image par défaut
				if (empty ($filename)) {
				 $mini='medias/images/default_picture.png';
				}else {
				 // Sinon, on utilise la photo uploadée
				 $mini=$CfgDir_Gallery.'/'.$int_title.'/'.$CfgDir_Photos.'/'.$CfgDir_Thumbs.'/'.$CfgDir_Thumbs_Mini.'/'.$filename;
				}

				// Si le titre de l'image est vide, on utilise le nom de fichier
				if (empty ($phototitle )) {
				 $title=$filename;
				} else {
				 // Sinon, on utilise le titre encodé dans la table
				 $title=$phototitle;
				}

			 // Affichage de la gallerie photo
			 echo '<div id="galleryDetail">
			 <div id="galleryDetailBorder">
			 <a href="'.$_SERVER['PHP_SELF'].'?galid='.$galid.'&intitle='.$int_title.'&file='.$filename.'" target="_self">
			 <img class="galleryDetailPicture1" src="'.$mini.'" alt="'.$filenameURL.'" /></a>
			 <p class="galleryDetailTitle1"><a href="'.$mini.'" target="_blank">'.$title.'</a></p>
			 </div>
			 </div>';
			}
		} else {

			// Sinon, on teste si $_GET[action] est = à diaporama
			if ($_GET['action'] == 'diapo') {

			 // On crée l'array des images
			 $photo_container = array ();

				// On récupère les éléments nécessaires
				while ($row = $req->fetch(PDO::FETCH_ASSOC)) {
				 $filename = $row['object_filename'];
				 $int_title = $row['gallery_int_title'];

				 // On récupère les noms des images de la base de donnée dans un array
				 array_push($photo_container,$filename);
				}

				 // On défini le répertoire des photos
				 $repertoire=$CfgDir_Gallery.'/'.$int_title.'/'.$CfgDir_Photos.'/'.$CfgDir_Thumbs.'/'.$CfgDir_Thumbs_Medium.'/';

				 // On compte le nombre de photos dans l'array et on retire 1 car on utilise le 0
				 $count = count($photo_container) -1;

				 // DEBUG OUTPUT
				 //echo 'Nombre d\'images: '.$count.'<br />';

				// On teste si la variable picture existe et si elle est plus petite que le nombre de photos dans l'array
				// Si elle eiste et est plus petite, on incrémente sinon, on reviens à la première image.
				if (isset ($_GET['pictid']) AND $_GET['pictid'] < $count) {
				 $i=$_GET['pictid'];
				 $i++;
				} else {
				 $i=0;
				}

				 // Diaporama automatique toutes les X secondes
				 echo '<div id="galleryDetailDiaporama"><img src="'.$repertoire.$photo_container[$i].'" alt="'.$photo_container[$i].'" /></div>';
				 echo '<meta http-equiv="refresh" content="'.$Diapo_NbSec.';URL='.$_SERVER['PHP_SELF'].'?galid='.$_GET['galid'].'&action=diapo&pictid='.$i.'" />';
			}
		}
		 
		 echo '<br class="spacer" />';
	}
	 echo '</body></html>';
?>

Merci pour tout,
Raph

Re: Double exécution d'une requête PDO

Posté : 06 févr. 2010, 16:35
par visualight
Salut,

J'ai peut etre enfin compris le pourquoi du comment mais j'en suis toujours au stade du comment faire pour que ça marche.

En effet, quand je clique sur une miniature pour l'afficher, le code interprète deux fois la même chose : Une fois sans boucle while et une autre fois avec une boucle. Ainsi j'obtiens le code suivant (en résumé) lors de l'exécution de ma page (quand je clique sur une miniature) :
$row = $req->fetch(PDO::FETCH_ASSOC);
$watermarkactif = $row['watermark_active'];

// puis un peu plus loin mon code exécute :

while ($row = $req->fetch(PDO::FETCH_ASSOC)) {}
SI JE NE ME TROMPE PAS, quand on interprète tout ça, l'image qui s'affiche en position 1 disparait (lorsque l'on clique dessus) parce que elle à été interprétée par le simple $row = $req->fetch(PDO::FETCH_ASSOC); (sans la boucle). La photo n°1 est donc "affichée" (réservée) au watermark.

Quand un peu plus loin, le code exécute la boucle while, il commence par la seconde miniature car la première a déjà été exécutée par le fetch_assoc (simple, sans la boucle ... celui du watermark).

Donc comment puis-je remédier à cela SANS faire deux requêtes (1 pour l'affichage des miniatures et une autre pour choper le watermark) ?

PS : Vous retrouverez le code complet de ma page au message précédent de ce même post


Merci pour votre aide,
raph

Re: Double exécution d'une requête PDO

Posté : 06 févr. 2010, 17:06
par visualight
OK ... J'avais vu juste

J'ai résolu mon problème en n'exécutant qu'une seule fois une boucle while et en stockant les photos dans un array
Puis un simple foreach et le tour est joué.

Désolé du dérangement,
Raph