Exclusion dans une boucle ou dans une requette SQL

Petit nouveau ! | 5 Messages

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

Mammouth du PHP | 686 Messages

15 févr. 2009, 01:16

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

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

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

Petit nouveau ! | 5 Messages

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

Petit nouveau ! | 6 Messages

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. ;)
Sethpolma (Jonathan Petitcolas)

Mammouth du PHP | 686 Messages

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

Petit nouveau ! | 5 Messages

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

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

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

Petit nouveau ! | 5 Messages

15 févr. 2009, 22:08

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