Page 1 sur 2

2 requètes

Posté : 10 janv. 2008, 19:05
par karenma
Bonsoir,

Je désire faire une recherche sur mon site avec 2 requètes.
J'ai dabord crée une table annonce 7 avec les champs texte,categorie et departement.

Voila le code de la 1ère page

Code : Tout sélectionner

<html > <head> <title>Document sans titre</title> <style type="text/css"> <!-- #Layer1 { position:absolute; left:62px; top:130px; width:627px; height:266px; z-index:1; } #Layer2 { position:absolute; left:70px; top:100px; width:647px; height:226px; z-index:1; } --> </style> </head> <body> <div id="Layer2"> <form id="form1" name="form1" method="post" action="recherche3.php"> <table width="527" height="160" border="0" cellpadding="0"> <tr> <td width="144"><div align="right"></div></td> <td width="186"><div align="center"> <select name="endroit" id="endroit"> <option value="00">tous les d&eacute;partements</option> <option value="75007">75</option> </select> </div></td> <td width="189"><div align="center"> <select name="quoi" id="quoi"> <option value="00">Toutes les cat&eacute;gories</option> <option value="voiture">voiture</option> </select> </div></td> </tr> <tr> <td height="58" colspan="3"><div align="center"> <input type="submit" name="Submit" value="rechercher" /> </div></td> </tr> </table> </form> </div> </body> </html>
qui renvoie a la page recherche3.php dont le code est le suivant

Code : Tout sélectionner

<html > <head> <title>Document sans titre</title> </head> <body> <?php $liendb = mysql_connect("nomduserveur","identifiant","passe"); mysql_select_db ("nomdelabase"); $sql= "SELECT texte FROM annonce7 WHERE categorie=$quoi AND departement=$endroit"; $resultat =mysql_query($sql); while ($eleve =mysql_fetch_array($resultat)) { $texte =$eleve['texte']; echo "$texte"; } mysql_close($liendb); ?> </body> </html>
Mais quand j'envoie le formulaire j'ai l'erreur
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /.../recherche3.php on line 13

Puis-je avoir de l'aide merci d'avance.

Posté : 10 janv. 2008, 20:13
par Ryle
Il faut commencer par comprendre le message d'erreur de php. Il te dit que l'argument passé à la fonction mysql_fetch_array() n'est pas une ressource MySQL valide.

Cela signifie que le contenu de ta variable $resultat n'est pas correct et ne peut être exploitée par les fonction mysql_fetch_*. Cette variable contient le résultat de l'exécution de mysql_query($sql), c'est à dire l'exécution de la requête. Si cette fonction de retourne une erreur, c'est donc qu'il y a eu un problème lors de l'exécution de la requête (problème de connexion, probleme de syntaxe, etc.)

Tu peux vérifier qu'une requête s'est exécutée correctement en ajoutant un test sur l'execution :
$resultat = mysql_query($sql) or die (mysql_error());
La fonction mysql_error() te permet de récupérer le message d'erreur le cas échéant et de savoir précisément où se situe l'erreur :)

En supposant que ta connexion à la base soit bonne, il faut donc vérifier la requête. Est ce que la table annonce7 existe ? est-ce qu'elle contient bien les champ "texte", "categorie" et "departement" ? est-ce que les variable $quoi et $endroit sont bien des nombres (sans quoi il faut les encapsuler d'apostrophes et éventuellement les protéger) ?

entre guillemets

Posté : 10 janv. 2008, 21:50
par karenma
salut
j'ai mis les guillemets entre '$quoi ' et '$endroit'
et ça marche!!
merci
mais je n'ai pas compris pourquoi tu dis
qu'il faut éventuellement les protéger
qu'est ce que ça veut dire?
Merci d'avance

Posté : 10 janv. 2008, 22:10
par karenma
encore moi je me demandais si rien ne correspond à la requete
comment mettre une phrase du style 'il n'y as pas de résultat' au lieu d'avoir une page blanche
comment dire requete vide? et à quel endroit le mettre dans le code?
Merci d'avance

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

Re: entre guillemets

Posté : 10 janv. 2008, 22:17
par AB
salut
j'ai mis les guillemets entre '$quoi ' et '$endroit'
et ça marche!!
merci
mais je n'ai pas compris pourquoi tu dis
qu'il faut éventuellement les protéger
qu'est ce que ça veut dire?
Merci d'avance
Il vaut mieux prendre l'habitude (à de rares exeptions près) de les protéger comme ça
"SELECT texte FROM annonce7 WHERE categorie= '" . mysql_real_escape_string($quoi) . "' AND departement= '" . mysql_real_escape_string($endroit) . "'";


Cliques sur la fonction mysql_real_escape_string() pour savoir pourquoi.

T'as vu Ryle j'ai pas utilisé sprintf :)

ajout d'un champs

Posté : 11 janv. 2008, 14:56
par karenma
Bonjour
Merci pour ton infos j'ai rajouté mysql_real_escape_string
et je voudrais aussi rajouter un champs texte avec la possibilité que ce champs texte soit vide
donc voici le code de ma 1ère page

Code : Tout sélectionner

<html > <head> <title>Document sans titre</title> <style type="text/css"> <!-- #Layer1 { position:absolute; left:62px; top:130px; width:627px; height:266px; z-index:1; } #Layer2 { position:absolute; left:70px; top:100px; width:647px; height:226px; z-index:1; } --> </style> </head> <body> <div id="Layer2"> <form id="form1" name="form1" method="post" action="recherche.php"> <table width="527" height="160" border="0" cellpadding="0"> <tr> <td width="144"><input name="mot" type="text" id="mot"></td> <td width="186"><div align="center"> <div align="right"> <select name="quoi" id="quoi"> <option value="avion">marre</option> <option value="voiture">voiture</option> </select> </div> </div></td> <td width="189"><div align="center"> <select name="endroit" id="endroit"> <option>touslesd&eacute;partements</option> <option value="13009">13009</option> </select> </div></td> </tr> <tr> <td height="58" colspan="3"><div align="center"> <input type="submit" name="Submit" value="rechercher" /> </div></td> </tr> </table> </form> </div> </body> </html>
et le nouveau code de ma 2ème page


Code : Tout sélectionner

<?php $liendb = mysql_connect("nomduserveur","identifiant","pass"); mysql_select_db ("nomdelabase"); if (empty($request['mot'])) $sql= "SELECT texte FROM annonce WHERE categorie= '$quoi' AND departement='$endroit'"; else $sql= "SELECT texte FROM annonce WHERE categorie= '$quoi' AND departement='$endroit' AND motcle1='".mysql_real_escape_string($mot)."'"; $resultat =mysql_query($sql) or die (mysql_error()); $nb_lignes = mysql_num_rows($resultat); $nb_colonnes = mysql_num_fields($resultat); echo "<table border=1 width=100% >"; for ($i=0; $i<$nb_lignes; $i++) { echo "<tr>"; for ($j=0; $j<$nb_colonnes; $j++) echo "<td>".mysql_result($resultat,$i,$j)."</td>"; echo"</tr>"; } echo"</table>"; echo "$texte"; mysql_close($liendb); ?>


et en fait le champs de texte qui soit vide ou pas vide il affiche tout le temps le même résultat à la requete

Merci d'avance

Posté : 11 janv. 2008, 17:14
par AB
Tes requêtes sont mal écrites. Une variable entre simple quote ' n'est pas interprétée. Il faut extraire toutes tes variables de la chaine comme ceci
$sql= "SELECT texte FROM annonce WHERE categorie = '" . mysql_real_escape_string($quoi) . "' AND departement = '" . mysql_real_escape_string($endroit) . "'";
else
$sql = "SELECT texte FROM annonce WHERE categorie= '" . mysql_real_escape_string($quoi) . "' AND departement = '" . mysql_real_escape_string($endroit) . "' AND motcle1 = '" . mysql_real_escape_string($mot) . "'"; 
(Quand tu écrit du code php dans le forum penses à utiliser la balise PHP plutôt que Code.)

Les espaces à droite et à gauche de mysql_real_escape_string et du point voisin sont là pour améliorer la sécurité de la requêtes, évites de les supprimer.

Posté : 11 janv. 2008, 17:27
par Ryle
Tu peux même construire ta requête en concaténant les morceaux de SQL dont tu as besoin plutôt que de devoir écrire deux fois la même requête à un critère près :)
$sql= "SELECT texte 
  FROM annonce 
  WHERE categorie= '" . mysql_real_escape_string($quoi) . "' 
  AND departement = '" . mysql_real_escape_string($endroit) . "'"; 

if (!empty($request['mot'])) 
  $sql.= " AND motcle1='".mysql_real_escape_string($mot)."'";
A noter que $request (que tu utilises dans ton if()) et $_REQUEST (qui contient les données envoyée en get ou post) sont deux variables totalement différentes... :)
Les espaces à droite et à gauche de mysql_real_escape_string et du point voisin sont là pour améliorer la sécurité de la requêtes
Euh... la lisibilité surtout parce que côté sécurité, l'espace fait pas grand chose :)
(et j'ai vu pour sprintf ;))

Posté : 11 janv. 2008, 17:43
par AB
Les espaces à droite et à gauche de mysql_real_escape_string et du point voisin sont là pour améliorer la sécurité de la requêtes
Euh... la lisibilité surtout parce que côté sécurité, l'espace fait pas grand chose :)
(et j'ai vu pour sprintf ;))
A bah j'avais lu ca il y a longtemps, avant que la fonction mysql_real_escape_string() soit disponible. Aujourd'hui c'est peut-être superflu mais avant il semble me souvenir que ça avait son utilité :-k

Enfin bref je ne me suis plus posé la question depuis bien longtemps puisque de toute façon comme tu le dis, au minimum ça améliore la lisibilité :)

champs vide

Posté : 11 janv. 2008, 17:55
par karenma
Salut

j'ai essayé ce code
$sql= "SELECT texte  
  FROM annonce  
  WHERE categorie= '" . mysql_real_escape_string($quoi) . "'  
  AND departement = '" . mysql_real_escape_string($endroit) . "'";  

if (!empty($request['mot']))  
  $sql.= " AND motcle1='".mysql_real_escape_string($mot)."'";
et j'ai tjrs la même réponse aux requetes que le champs texte soit vide ou pas vide


sinon je n'est pas très bien compris ce code est ce que je ne dois pas mettre de if??

sinon n'est ce pas la même chose que ce que j'ai posté

$sql= "SELECT texte FROM annonce WHERE categorie = '" . mysql_real_escape_string($quoi) . "' AND departement = '" . mysql_real_escape_string($endroit) . "'"; 
else 
$sql = "SELECT texte FROM annonce WHERE categorie= '" . mysql_real_escape_string($quoi) . "' AND departement = '" . mysql_real_escape_string($endroit) . "' AND motcle1 = '" . mysql_real_escape_string($mot) . "'"; 


enfin je suis un peu perdue puis je avoir une aide merci d'avance.

Posté : 11 janv. 2008, 18:06
par Ryle
Au niveau code c'est la même chose effectivement, je me suis juste contenté de mutualiser le début de la requête qui est identique dans les deux cas pour ne l'avoir qu'une seule fois. Cela allège ton code et facilite la maintenance puisqu'en cas de correction ou d'évolution, les modifs à faire dessus ne se font pas en double ;)

Concernant le problème du au fait que le champ texte soit vide ou non qui ne change rien, c'est sans doute parce que la variable que tu testes " $request['mot'] " n'existe pas. Du coup, c'est toujours la requête sans ce critère qui est exécutée.
Si tu veux faire appel aux variables qui ont été transmises à ta page dans la requête http, c'est $_REQUEST qu'il te faut utiliser (avec le sousligné et les majuscule, php est très pointilleux avec ses variables ;)). Tu pourrais aussi utiliser $_POST['mot'] puisque le formulaire envoi les données en post :)

Posté : 11 janv. 2008, 18:10
par AB
Ton code de plus haut avec les les variables extraites donne ça.
<?php
$liendb = mysql_connect("nomduserveur","identifiant","pass");
mysql_select_db ("nomdelabase");
if (empty($_POST['mot']))
$sql= "SELECT texte FROM annonce WHERE categorie = '" . mysql_real_escape_string($quoi) . "' AND departement = '" . mysql_real_escape_string($endroit) . "'"; 
else 
$sql = "SELECT texte FROM annonce WHERE categorie= '" . mysql_real_escape_string($quoi) . "' AND departement = '" . mysql_real_escape_string($endroit) . "' AND motcle1 = '" . mysql_real_escape_string($mot) . "'";
$resultat =mysql_query($sql) or die (mysql_error());
$nb_lignes = mysql_num_rows($resultat);
$nb_colonnes = mysql_num_fields($resultat);
echo "<table  border=1 width=100% >";
for ($i=0; $i<$nb_lignes; $i++)
{
echo "<tr>";
for ($j=0; $j<$nb_colonnes; $j++)
echo "<td>".mysql_result($resultat,$i,$j)."</td>";
echo"</tr>";

}
echo"</table>";
echo "$texte";


mysql_close($liendb);
?>
Ryle t'a proposé une petite amélioration. Il y a bien un if dans son code : if (!empty($request['mot'])) qui complète la requête si !empty($request['mot'] existe et est non vide.
Ce que t'a proposé Ryle est plus optimisé mais ça produira le même résultat. Evidemment si tu ne connais pas la concaténation de chaines ça te fait ça de plus à comprendre mais c'est un bon exemple didacticiel :wink:

EDIT j'ai corrigé ton code suivant la remarque de Ryle ($_POST['mot'] à la place de $request['mot'])

Posté : 11 janv. 2008, 18:21
par AB
Oulà ! et si tu nous montre tout ton code il y a d'autres fautes.. Tu ne définis pas tes variables $quoi , $departement et $mot avant de les utiliser dans tes requêtes #-o

Une fois corrigé la partie requête cela devrait donner quelque chose comme ça
<?php

function stripgpc($value) {
if(get_magic_quotes_gpc()) $value = stripslashes($value);
return $value;
}

$liendb = mysql_connect("nomduserveur","identifiant","pass");
mysql_select_db ("nomdelabase");

$quoi = !empty($_POST['quoi'])? mysql_real_escape_string(stripgpc($_POST['quoi'])) : '';
$endroit = !empty($_POST['endroit'])? mysql_real_escape_string(stripgpc($_POST['endroit'])) : '';
$mot = !empty($_POST['mot'])? mysql_real_escape_string(stripgpc($_POST['mot'])) : '';

if (empty($_POST['mot'])) 
$sql= "SELECT texte FROM annonce WHERE categorie = '" . $quoi . "' AND departement = '" . $endroit . "'"; 
else 
$sql = "SELECT texte FROM annonce WHERE categorie= '" . $quoi . "' AND departement = '" . $endroit . "' AND motcle1 = '" . $mot . "'";

$resultat =mysql_query($sql) or die (mysql_error());
$nb_lignes = mysql_num_rows($resultat);
$nb_colonnes = mysql_num_fields($resultat); ?>
Pourquoi j'ai ajouté une petite fonction stripgpc ? La réponse ici http://www.phpfrance.com/forums/voir_re ... php#228257

Cela te permettras de pouvoir inclure des mots avec apostrophe (ex: cote d'or) sans rencontrer de pb de configuration de serveur. Chez free par exemple, get_magic_quotes_gpc() est activé donc sans cette petite fonction, ta requête échouaierait puisque le mot recherché serait : cote d\'or

2 ou 3 mots differents

Posté : 13 janv. 2008, 12:22
par karenma
Salut

Un grand merci pour vos réponses ça marche et aussi merci pour l'infos concernant l'apostrophe.

j'ai essayé le code suivant et ça marche.
<?php 

function stripgpc($value) { 
if(get_magic_quotes_gpc()) $value = stripslashes($value); 
return $value; 
} 

$liendb = mysql_connect("nomduserveur","identifiant","pass"); 
mysql_select_db ("nomdelabase"); 

$quoi = !empty($_POST['quoi'])? mysql_real_escape_string(stripgpc($_POST['quoi'])) : ''; 
$endroit = !empty($_POST['endroit'])? mysql_real_escape_string(stripgpc($_POST['endroit'])) : ''; 
$mot = !empty($_POST['mot'])? mysql_real_escape_string(stripgpc($_POST['mot'])) : ''; 

if (empty($_POST['mot']))  
$sql= "SELECT texte FROM annonce WHERE categorie = '" . $quoi . "' AND departement = '" . $endroit . "'";  
else  
$sql = "SELECT texte FROM annonce WHERE categorie= '" . $quoi . "' AND departement = '" . $endroit . "' AND motcle1 = '" . $mot . "'"; 

$resultat =mysql_query($sql) or die (mysql_error()); 
$nb_lignes = mysql_num_rows($resultat); 
$nb_colonnes = mysql_num_fields($resultat); ?> 
Mais je me demandais aussi par exemple si dans le champs texte on tape 2 ou 3 mots clés comme
peugeot renault opel comment faire afficher tout les résultats de requète et pas la requète qui contient les 3 mots clés.
je ne sais pas si c'est possible et si oui comment faire?
Merci d'avance pour votre réponse.

Posté : 13 janv. 2008, 23:15
par AB
Sur le principe tu fais un explode sur la valeur envoyée par le champ texte
$tab = explode(' ', $_POST['tex']);

Tu liste les éléments tu tableau $tab et en fonction du résultat tu crée ta requête de façon dynamique comme te l'a montré Ryle (son exemple va te servir plus vite que prévu ) :wink:

pour obtenir
WHERE voiture = 'renault' OR voiture ='peugeot' etc.