Bonjour, bonsoir je suis actuellement un peux bloqué. Jai cree un formulaire avec 9 selects qui peuvent etre remplis ou non. Par exemple seulement 2 select sur les 9 peuvent etre remplis cest selon lutilisateur. Chaque select renvoie un enregistrement dun champs de ma base de donnee ces 9 selects du formulaire represente donc 9 champs dune de mes table. Et donc je bloque comment faire ma requete finale en ne sachant pas combien de donnee ne vais recevoir et lesquelle ?
Jespere mettre fais comprendre, si vous avez besoin de plus de precision nhesitez pas.
Merci.
Je suis pas sur d'avoir compris, tu veux faire quoi au juste ?
Récupérer les éléments de ta table ? ![]()
Oui voila chaque select de la liste déroulante renvoie à un champs d'une table.
Et chaque option de ces select à un trie de leurs enregistrements.
Par exemple la liste 1 est sur le champ 'Taille' et dessus on peux sélectionner certaines option comme >1m50 et <1m50.
Et ça avec 9 select donc 9 champs.
Et à la fin j'ai un ou plusieurs résultat en fonction du trie que l'utilisateur aura chosit.
Le problème c'est que l'utilisateur n'est pas obliger de choisir les 9 select.
Donc pour la requête je ne sais pas ce qui sera présent dans le WHERE, la requête sera différente selon ce que l'utilisateur aura sélectionné
Il faut construire la clause WHERE de ta requête SQL dynamiquement.
Voici une idée de départ :
$selectDeBase = "Select * from produits";
$conditions = array();
if( $hauteurSelectionnee != null) {
$conditions = "hauteur > ". (int)$hauteurSelectionnee;
}
if( $largeurSelectionnee != null) {
$conditions = "largeur > ". (int)$largeurSelectionnee;
}
$selectFinal = $selectDeBase;
if( count($conditions) > 0 ) {
$selectFinal .= " WHERE ". implode(" AND ", $conditions);
}
echo $selectFinal;
Et faire super, super gaffe au risque d'injection SQL.
Je suis encore pas tout à fait sur d'avoir compris, désolé mais je dois être chiant
Tu veux donc récupérer dans des listes les contenus de tes champs ?
J'ai pas bien compris en quoi les champs optionnels te posent problème, enfin pour chaque champ tu fais :
SELECT champ FROM table
Et si t'as un champ vide bah t'auras une liste vide, mais c'est normal et je vois pas trop le soucis
Après pour faire un where dynamique, bah tu peux construire ta requête comme ça :
SELECT *
FROM machin
WHERE truc = (sous requête)
La condition du WHERE t'en fais ce que tu veux, =, >, ...
Et la sous requête te permet d'avoir justement une condition "dynamique"
Genre WHERE truc >= (SELECT machin FROM chouette ...) ![]()
Cest skip qui a trouvait la reponse il me manquait le implode en faite je ne le connaissais pas. Pour securiser a la fin de la requete si le resultat coreespond a un enregistrement de ma table cest ok sinon cest retour a lenvoyeur ? Avec quelque htmlspecialchars() et sa fera laffaire non ?
Non, il faut intervenir sur les valeurs fournies avant de lancer la requête.
Des explications sur le problème ici : http://php.net/manual/fr/security.database.sql-injection.php
Intervenir avant de lancer la requete cad que je dois verifier que chaque !empty select (cad ce que lutilisateur aura selectionné) corresponde a un resultat avec ma requete ? Je ne vois pas trop comment faire pourrez tu meclairsir sur le sujet stp merci.
Faut juste vérifier que ce que tu reçois sur ta page.php corresponde à ce que attende. Parce qu'en fait pour envoyer une requête POST ou GET à ton fichier.php comme le fait ton formulaire on n'a pas besoin d'utiliser ton formulaire.
En gros on peut envoyer n'importe quoi comme requête à ton fichier.php donc il faut que tu dégages toutes les requêtes qui ne correspondent pas à celles attendues.
Ok donc si j'ai bien compris je dois vérifier que chaque select non vide contiennent certain caractères précis et non pas n'importe quoi.
Par exemple :
if(isset($_POST['taille']) && !empty($_POST['taille']))
{
if($_POST['taille'] == "1,50m" OR $_POST['taille'] == "1,70m" ...)
{
// J'enregistre le contenus dans une variable pour effectuer ma requête
}
else
{
// ERREUR
}
}
C'est bien ça ?
Merci Bien!
Oui enfin cela dépend du niveau de gestion d'erreurs souhaité.
Tu peux aussi simplement échapper les caractères indésirables ou passer par des requêtes préparées.
Je ne connais pas les requêtes préparée pourrais tu m'éclaircir sur le sujet, en quoi elles consistent et comment les utiliser ?
Merci.
Une requête préparé c'est ça ?
$req=$bdd->prepare("SELECT FROM WHERE");
$req->execute(array());
$res=$req->fetch();
Si oui c'est ce que j'ai fais pour tout mon code.
Sinon comment je peux échapper certain caractère ? Toujours avec une condition ou il y a autre chose à faire ?
Oui c'est ça.
Autrement : http://php.net/manual/fr/security.database.sql-injection.php
Si $_POST['couleur'] = 'Jaune';
Est ce que je peux faire ça ? :
$req=$bdd->prepare("SELECT id FROM table WHERE couleur = ? ");
$req->execute(array( $_POST['couleur'] ));
$res=$req->fetch();
if(isset($res['id']))
{
// OK
}
else
{
// ERREUR
}
Sa me semble sécurisé et je n'aurais pas à retouché le PHP si je créer de nouvelle couleurs dans ma table.
Faut t'il rajouter un !empty ou le isset est suffisant ?
Merci.
Ou alors avec un COUNT(*) dans le SELECT à la place du id et je demande si COUNT(*) >=1.
Quel solution est la plus viable ?
Merci.
Oui c'est sécurisé.
Comment construire ta requête?
Cela va dépendre de ton nombre de données, en effet un premier filtre peut filtrer assez de données pour se permettre de toutes les garder pour appliquer un second filtre traité par PHP.
Autrement, si les variables POST sont définies (et tant qu'à faire non vides puisqu'on ne va pas filtrer sur un critère qui n'élimine aucune donnée) tu va passer par une variable texte :
$reqprep = "SELECT id FROM table WHERE";
$reqaexec = array();
$verif = 0;
if (isset($_POST['couleur']) && !empty($_POST['couleur'])) {
|| $reqprep .= " couleur = ?";
|| $verif += 1;
}
if (isset($_POST['taille']) && !empty($_POST['taille'])) {
|| $reqprep .= " taille > ?";
|| $verif += 1;
}
etc.
if ($verif == count($_POST)) {
|| $req=$bdd->prepare($reqprep);
|| $req->execute($_POST);
|| $res=$req->fetch();
}
Tu vois l'idée, bon je n'ai pas vérifié si ça fonctionne, par contre il va falloir faire très attention à l'ordre à l'intérieur du tableau $_POST puisque tu en seras très dépendant.
Je n'ai pas bien compris ce que tu voulais faire avec ton count.
Autrement petite correction, cette ligne :
|| $reqprep .= " taille > ?";
devient bien évidemment :
|| $reqprep .= " AND taille > ?";
Pareil :
if ($verif == count($_POST)) {
devient :
if ($verif > 0 && $verif == count($_POST)) {
Puisqu'on ne va pas lancer de requête si aucun critère n'est demandé.