Une requête php/mysql un peu compliquée (enfin, pour moi en tout cas :D)

Petit nouveau ! | 2 Messages

19 mai 2008, 14:38

Bonjour à tous!
Et à toutes! (vive l'égalité des sexes et tout ça)

Alors voilà, j'ai un problème, je n'arrive pas à "formater" correctement ma requête Mysql :

Imaginons une bdd comme suit:
(bon j'écris le mot CREATE TABLE sinon je peux pas poster :lol: )

Code : Tout sélectionner

table fichiers: id nom titre auteur parution numero rub mc table mc: id mc table rubriques: id rub
*un fichier ne peut avoir qu'un seul mc (mot-clé) et qu'une seule rubrique. (sinon j'aurais fais une table de liaison, enfin bref...)

Alors imaginons un formulaire du genre:
<link rel="stylesheet" type="text/css" href="../../css/main.css" />
<link rel="stylesheet" type="text/css" href="../../css/form.css" />
<p class="titre3"><a href="admin.php?fuseaction=choix">Revenir aux choix:</a></p>


<form id="monForm" name="monForm" action="rechercher_func.php" method="post">
<fieldset>
<legend>Ajouter</legend>
<p>
	<label for="form_titre">Titre : (ex: plaine à Uccle)</label>
    <input type="text" id="form_titre" name="titre" />
</p>
<p>
	<label for="form_auteur">Auteur : </label>
    <input type="text" id="form_auteur" name="auteur" />
</p>
<p>
	<label for="form_numero">Numéro du Badje Info : (ex: 21)</label>
    <input type="text" id="form_numero" name="numero" />
</p>
<p>
	<label for="form_parution">Date de parution : (ex: Juin 2008)</label>
    <input type="text" id="form_parution" name="parution" />
</p>
<p>
<label for="form_rub">Rubriques : </label>
<select name="form_rub[]" size="4" multiple>
<option value="choix">Votre choix
<?php
include 'connect.php';
$sql = 'SELECT id,rub FROM rubriques ORDER BY rub';
$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());
// on fait une boucle qui va faire un tour pour chaque enregistrement
while ($row = mysql_fetch_array($req, MYSQL_BOTH))
{
	echo "<option value=".utf8_encode($row[0]).">".utf8_encode($row[1])." ";
} 
mysql_close();
?>
</select>
</p>
<p>
<label for="form_mc">Mots-clés : </label>
<select name="form_mc[]" size="4" multiple>
<option value="choix">Votre choix
<?php
include 'connect.php';
$sql = 'SELECT id,mc FROM mc ORDER BY mc';
$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());
while ($row = mysql_fetch_array($req, MYSQL_BOTH))
{
	echo "<option value=".utf8_encode($row[0]).">".utf8_encode($row[1])." ";
} 
mysql_close();
?>
</select>
</p>

</fieldset>

<p>
    <input type="submit" name="submit" value="Ajouter" />   
</p>
</form>
les listes se remplissent donc grâce à la bdd, comme vous l'avez vu.

Alors, l'user choisi un critère ou plusieurs (chaque critère peut être pris séparément ou ensemble), il envoie le form à la deuxième page qui va traiter les données et faire la requête, j'ai fais un truc genre:
<?php
//Variables:
$titre = $_POST['titre'];
$auteur = $_POST['auteur'];
$numero = $_POST['numero'];
$mc = $_POST['form_mc[]'];
$rub = $_POST['form_rub[]'];
//-------------------------
include 'connect.php';
//---
$requete = "SELECT * FROM fichiers,mc,rubriques";
//Argument prioritaire:
if ($titre !="")
{
	$requete = "WHERE fichiers.titre = $titre";
}else if ($auteur !="")
{
	$requete = "WHERE fichiers.auteur = $auteur";
}else if ($numero !="")
{
	$requete = "WHERE fichiers.numero = $numero";
}else if (sizeof($mc)!=0)
{
	$requete = "WHERE fichiers.mc = mc.id AND mc.id = $mc[0]"; 
}
}else if (sizeof($rub)!=0)
{
	$requete = "WHERE fichiers.rub = rubriques.id AND rubriques.id = $rub[0]"; 
}else
{
	echo "Veuillez au moins choisir un critère de sélection !";
}
//---
//Arguments secondaires:
//heu...

$resultat = mysql_query($requete) or die ("Erreur dans la requete : " . mysql_error());
//---
mysql_close();
//---
//Nouvelle recherche:
echo '<a href="admin.php?fuseaction=recherche">Faire une nouvelle recherche</a>';
?>
Comme vous pouvez le constater, ma requête est incomplète (et le début est peut-être pas bon)...
Donc voici ma question, comment faire pour arriver à faire une requête, en prenant en compte tous les cas de figure (style, l'user choisi un auteur, et une rubrique, ou juste 3 mots-clés (sélection multiple))
Je ne vois vraiment pas comment faire, là j'étais parti sur l'idée de faire un "argument prioritaire" qui serait traduit par un "WHERE" et des arguments secondaires, qui seraient traduits par des "AND"...
Mais dans mon cas de figure, imaginons que ce soit auteur, l'argument prioritaire, je devrais faire un flag pour le signaler, et j'aurais ensuite un
si mon flag est égal à "auteur" alors tatata, si mon flag est égal à "titre" alors blublublu... ça me parait fort répétitif (voire rébarbatif), beaucoup de if, j'ai l'impression qu'il y'a moyen de faire plus simple et que je me suis fourvoyé quelque part :s

A priori je ne demande pas un code tout fait tout propre, mais peut etre une sorte de "framework" je vais dire, qui m'aiderait a visualiser la marche à suivre.
I mean... le code je sais l'écrire, faire une requête normale, c'est pas dur, mais là c'est la conception des conditions/ choix de l'user qui me compliquent la vie :s
(et est-ce que ma bdd est bien pensée ou pas?)

Et si vous avez des questions, si j'ai pas été clair, si vous voulez les .sql pour faire des tests chez vous, faites moi signe ;)

Mammouth du PHP | 1353 Messages

19 mai 2008, 15:45

Je pense que tu ferais mieux d'utiliser la concaténation.
Tu constuit ta condition "au fur et à mesure".

Par exemple :
$requete = "SELECT * FROM fichiers,mc,rubriques"; 
//Argument prioritaire: 
$conditons = "";
if ($titre !="") 
{ 
    if(!$conditions) $condition.="WHERE ";
    else $condition." AND ";
    $conditions .= "fichiers.titre = $titre"; 
}

if ($auteur !="") 
{ 
    if(!$conditions) $condition.="WHERE ";
    else $condition.=" AND ";
    $conditions .=  "fichiers.auteur = $auteur"; 
}

if ($numero !="") 
{ 
    if(!$conditions) $condition.="WHERE ";
    else $condition.=" AND ";
    $conditions .=  "fichiers.numero = $numero"; 
}
$requete .= $conditions;
//--- 
C'est pas le code idéal mais en gros l'idée est la suivante :
tu crée une variable qui est vide et dès que tu trouves une condition tu la concatènes à ta variable donc à la fin ca fait une requête complète.
Tell me and I forget. Teach me and I remember. Involve me and I learn.

Eléphant du PHP | 175 Messages

19 mai 2008, 15:59


Petit nouveau ! | 2 Messages

19 mai 2008, 16:06

aah, terrible comme idée!
C'est exactement ça que je cherchais...
Bon, pour les listes ça va être une autre paire de manches mais bon...
en tout cas merci beaucoup, je vais pouvoir avancer !


:merci: melci honolable guilt92

ps: merci à toi aussi steph29, même si c'est plus compliqué tout de suite :s

EDIT:
Ceci ne fonctionne pas:

Code : Tout sélectionner

if(!$conditions) $condition.="WHERE "; else $condition." AND "; $conditions .= "fichiers.titre = $titre";
il me renvoie ceci comme erreur:
Erreur dans la requete : Table/alias: 'fichiers' non unique
(et il y avait des s qui manquaient à "condition" à plusieurs endroits mais ça j'ai géré comme un grand :p)
Je vois pas ce que ça veut dire comme erreur :s ?