Exclusion dans une boucle ou dans une requette SQL

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Exclusion dans une boucle ou dans une requette SQL

par BberXIII81 » 15 févr. 2009, 22:08

Super, pile ce qui me faillais, merci à tous. :D

par Ryle » 15 févr. 2009, 21:43

@BberXIII81 : ca signifie "est différent de", c'est la même chose que " != " (bien que personnellement je recommande d'avantage l'usage de ce dernier qui est compatible avec d'avantages de bases de données)

Tu peux aussi, si jamais tu souhaites exclures plusieurs id, utiliser la syntaxe IN() et le mot clé NOT :
$sql = 'SELECT ..... FROM news WHERE id NOT IN ('.$listeDidSéparésParDesVirgules.')';

@sylvaing26 : une injection, c'est lorsqu'un utilisateur malveillant parvient à détourner une de tes requêtes pour qu'elle fasse autre chose que ce que tu avais prévu.

Le mieux étant sans doute un exemple, supposons une requête d'authentification qui serait la suivante :
"SELECT id, nom, prenom FROM users WHERE login = '".$_POST['login']."'";
En toute logique, l'utilisateur spécifie son login dans un formulaire, la requête s'exécute avec le critère " WHERE login = 'toto' " et renvoi l'enregistrement correspondant s'il existe.

L'injection consisterait pour l'utilisateur à spécifier à la place de son login une chaine du genre : " ' OR '1'='1 ". Si la variable n'est pas protégée et utilisée telle quel, ton critère devient : " WHERE login = '' OR '1'='1' ". Résultat, la condition 1=1 étant toujours vrai, ta base de données retournera l'ensemble des id/nom/prenom qu'elle contient.

Grace aux injections, un utilisateur malveillant pourrait ainsi également faire des jointures sur d'autres tables, découvrir la structure de ta base, voire l'altérer...

Il convient donc de protéger les variables avant de les passer dans une requête (mysql_real_escape_string() fait ça très bien pour les chaines, mais les magic quotes ou un addslashes peuvent donner de bons résultats également). Ma requête devient donc
"SELECT id, nom, prenom FROM users WHERE login = '".mysql_real_escape_string($_POST['login'])."'";
Ce qui aura pour effet, si l'utilisateur tente une injection de retourner :
" WHERE login = '\' OR \'1\'=\'1' ", la requête ne retourne ainsi aucun résultat :)

par BberXIII81 » 15 févr. 2009, 17:42

Ou, plus simplement, tu dois bien récupérer l'id de la news que le visiteur souhaite lire, non ? Dans ce cas, il te suffit de changer ta requête SQL :

Code : Tout sélectionner

$sql = 'SELECT * FROM news WHERE id <> '.$id;
En protégeant l'id, bien entendu. Ce serait bête d'avoir une petite injection. ;)
"<>" dans la requête SQL signifierais "Tout sauf ce qui suit" ? Si c'est celà, c'est parfaitement ce que je cherchais

par sylvaing26 » 15 févr. 2009, 16:14

Ce serait bête d'avoir une petite injection. ;)
J'ai jamais compris ce que c'étais ces injections, peux tu expliquer s'il te plait ? Parce que je ne suis pas accro a celles ci ... (la blague) :D

par Sethpolma » 15 févr. 2009, 15:04

Ou, plus simplement, tu dois bien récupérer l'id de la news que le visiteur souhaite lire, non ? Dans ce cas, il te suffit de changer ta requête SQL :

Code : Tout sélectionner

$sql = 'SELECT * FROM news WHERE id <> '.$id;
En protégeant l'id, bien entendu. Ce serait bête d'avoir une petite injection. ;)

par BberXIII81 » 15 févr. 2009, 11:27

Malheureusement non, le critère de sélection (qui correspond à la news que le visiteur veux afficher en entier) ne se trouve pas dans ma base de données.

Mais j'ai trouvé une solution qui me va beaucoup mieux...
Au lieu d'ouvrir la news que le visiteur à choisit de lire en haut de ma page et d'ôter son titre de la liste des autres news disponibles qui se trouvent en dessous (comme je voulais le faire), la news choisie s'ouvre à l'intérieur de la boucle de titre grâce à une condition.

En vous remerciant pour vos réponses

par Ryle » 15 févr. 2009, 03:22

Si le critère d'exclusion est présent dans ta base de données, le plus simple est effectivement de faire le tri dans les enregistrements que tu récupères dès la requête SQL (inutile de ramener des enregistrements si c'est pour ne pas les traiter)

Dans ce cas, il suffit de jouer avec les conditions WHERE AND/OR. Par exemple si tu veux uniquement afficher les news pour lesquelles le champ "actif" de ta base aurait la valeur "1", il te suffirait d'écrire ta requête ainsi :
$sql = "SELECT mes_champs, .... FROM ma_table WHERE actif = 1";
De même si tu veux afficher uniquement celles supérieure où égale à la date du jour ("... WHERE ma_date >= NOW() ") ou celles dont l'objet commence par un "Z" ("... WHERE objet LIKE 'Z%' ") ....

Sinon, tu peux effectivement, comme l'a suggéré sylvaing26, ajouter un if() dans ta boucle et passer à l'itération suivante en utilisant l'instruction "continue" :)

par sylvaing26 » 15 févr. 2009, 01:16

Essaie avec quelque chose de ce genre là
while($result = ...){
if(!$result == $lanewsapasafficher){
...
}
}

Exclusion dans une boucle ou dans une requette SQL

par BberXIII81 » 15 févr. 2009, 00:12

Bonsoir,

Je souhaiterais savoir si il est possible (et comment) d'exclure une entrée lorsque je fais une boucle (while ou for) avec des données d'une table.

Pour exemple, j'affiche les news contenue dans ma base de donnée grâce à une boucle mais je ne veux pas en afficher une en fonction d'une variable.

J'espère que ce que je raconte vous serra compréhensible mais j'en suis pas sûr :?

En vous remerciant d'avance,

Bertrand