2 requètes

Eléphant du PHP | 83 Messages

10 janv. 2008, 19:05

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.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

10 janv. 2008, 20:13

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) ?
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 83 Messages

10 janv. 2008, 21:50

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

Eléphant du PHP | 83 Messages

10 janv. 2008, 22:10

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]

ViPHP
AB
ViPHP | 5818 Messages

10 janv. 2008, 22:17

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 :)

Eléphant du PHP | 83 Messages

11 janv. 2008, 14:56

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

ViPHP
AB
ViPHP | 5818 Messages

11 janv. 2008, 17:14

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.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

11 janv. 2008, 17:27

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 ;))
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

ViPHP
AB
ViPHP | 5818 Messages

11 janv. 2008, 17:43

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é :)

Eléphant du PHP | 83 Messages

11 janv. 2008, 17:55

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.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

11 janv. 2008, 18:06

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 :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

ViPHP
AB
ViPHP | 5818 Messages

11 janv. 2008, 18:10

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'])

ViPHP
AB
ViPHP | 5818 Messages

11 janv. 2008, 18:21

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

Eléphant du PHP | 83 Messages

13 janv. 2008, 12:22

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.

ViPHP
AB
ViPHP | 5818 Messages

13 janv. 2008, 23:15

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.
Modifié en dernier par AB le 14 janv. 2008, 04:54, modifié 1 fois.