IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Plusieurs possibilités pour where


Sujet :

PHP & Base de données

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut Plusieurs possibilités pour where
    Bonjour à tous

    Alors voilà j'ai un petit problème.
    Je ne connais pas grand chose au SQL alors je me tourne vers vous.

    Pour accéder à l'épisode 1 de la saison 1 de mon site, je fais
    mondomaine.com/episode.php?id=1
    Et dans le fichier PHP, ça donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $retour = mysql_query("select * from episode where id=$id");
    jusque la, ca fonctionne


    Mais je voudrais que le lien pour accéder à l'épisode 1 de la saison 1 soit
    mondomaine.com/episode.php?saison=1&episode=1
    donc je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $retour = mysql_query("select * from episode where saison=$saison AND episode=$episode");
    Et ça fonctionne aussi

    Mon problème, c'est qu'en faisant ça, le lien mondomaine.com/episode.php?id=1 ne fonctionne plus

    et je voudrais que l'épisode soit accessible par
    mondomaine.com/episode.php?id=1
    ET PAR
    mondomaine.com/episode.php?saison=1&episode=1


    j'ai essayer de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $retour = mysql_query("select * from episode where id=$id OR saison=$saison AND episode=$episode");
    mais ça fonctionne pas

    Je sais bien que c'est pas très clair, mais je ne sais pas comment expliquer.

    En tous cas, merci à ceux qui prendront le temps de me répondre

  2. #2
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Un truc comme ça, par exemple ?
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $sql = "select * from episode where " ;
    if ($id) { $sql .= "id = $id" ; } else {$sql .= "saison = $saison AND episode = $episode"} ;
    $retour = mysql_query($sql);

  3. #3
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Attention au injections SQL /!\


    Tu as oublié les parenthèses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $retour = mysql_query('select * from episode where id='.intval($id).' OR (saison='.intval($saison).' AND episode='.intval($episode).')');
    A supposé que tu n'ai pas d'entrées '0'

  4. #4
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 287
    Par défaut
    Citation Envoyé par |PaRa-BoL Voir le message
    Attention au injections SQL /!\
    Je propose qu'on traite un problème à la fois. D'abord le fonctionnement d'ensemble, ensuite il n'y aura plus qu'à ajouter quelques lignes en début de code pour valider/sécuriser les variables extérieures... s'agissant de trois entiers, ça ne devrait pas être trop dur !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    $id = (int) $id ;
    $saison = (int) $saison ;
    $episode = (int) $episode ;

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut

    Ca fonctionne pas : Parse error: syntax error, unexpected '}' in [...]

    Au final ca me donnait ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php
    mysql_connect("...", "...", "...");
    mysql_select_db("...");
     
    $sql = "select * from episode where " ;
    if ($id) { $sql .= "id = $id" ; } else {$sql .= "saison = $saison AND episode = $episode"} ;
    $retour = mysql_query("$sql");
    while ($donnees = mysql_fetch_array($retour))
    {
    ?>

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut

    Ah voilà, ca fonctionne impeccablement bien !

    Donc au final j'ai mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    mysql_connect("...", "...", "...");
    mysql_select_db("...");
    // On récupère les 5 dernières news
    $retour = mysql_query('select * from episode where id='.intval($id).' OR (saison='.intval($saison).' AND episode='.intval($episode).')');
    while ($donnees = mysql_fetch_array($retour))
    {
    ?>

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut
    J'en reviens pas, j'ai cru que c'était peine perdue !
    3 semaines de recherches, et là, à 3h00 du matin, la réponse !
    Vraiment merci

    Quelqu'un peut m'expliquer c'est quoi "intval" ?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut
    Quelqu'un m'a dit que c'est une mauvaise idée, car ça fait un "duplicate content".
    C'est grave ?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut
    Pour éviter le duplicate content, j'ai mis en place une redirection.
    Donc celui qui entre sur episode.php?id=1 doit arriver sur saison-1-episode-1.html

    J'ai donc mis ça dans mon .htacces
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    RedirectPermanent /episode.php?id=1  http://www.monsite.com/saison-1-episode-1.html
    RedirectPermanent /episode.php?id=2  http://www.monsite.com/saison-1-episode-2.html
    RedirectPermanent /episode.php?id=3  http://www.monsite.com/saison-1-episode-3.html
    Et ainsi de suite...


    Malheureusement, ça fonctionne pas
    J'ai jeté un coup d'œil sur google, pas de solutions...

  10. #10
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2005
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2005
    Messages : 357
    Par défaut
    Salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #ici on récupère les deux variables. qu'elles soient passées ou pas.
    if (isset($_GET[episode]) $episode= $_GET[episode]; else $episode = '';
    if (isset($_GET[saison]) $saison= $_GET[saison]; else $saison= '';
    if (isset($_GET[id]) $id= $_GET[id]; else $id= '';
     
    $cond = '';
    if ($id!= '') $cond = " id= '" . $id. "'";  / si on fournit un id
    else {  //  si on fournit un épisode et/ou une saison
      if ($saison != '') $cond = " saison = '" . $saison . "'";
      if ($episode != '') {
        if ($cond != '') $cond .= ' and ';
        $cond .= " episode = '". $episode . "'";
      }
    }
    if ($cond == '') $cond = " 1"; // récuperer tous les épisodes de toutes les saisons
     
     
    $qry = "select * from episode where $cond"

  11. #11
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Citation Envoyé par beeboo Voir le message
    Salut,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #ici on récupère les deux variables. qu'elles soient passées ou pas.
    if (isset($_GET[episode]) $episode= $_GET[episode]; else $episode = '';
    if (isset($_GET[saison]) $saison= $_GET[saison]; else $saison= '';
    if (isset($_GET[id]) $id= $_GET[id]; else $id= '';
     
    $cond = '';
    if ($id!= '') $cond = " id= '" . $id. "'";  / si on fournit un id
    else {  //  si on fournit un épisode et/ou une saison
      if ($saison != '') $cond = " saison = '" . $saison . "'";
      if ($episode != '') {
        if ($cond != '') $cond .= ' and ';
        $cond .= " episode = '". $episode . "'";
      }
    }
    if ($cond == '') $cond = " 1"; // récuperer tous les épisodes de toutes les saisons
     
     
    $qry = "select * from episode where $cond"
    Très lourd pour rien...
    Et sécuriser les variables envoyées à MySQL on s'en moque ?

  12. #12
    Membre Expert Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 895
    Par défaut
    le plus simple, est de tout mettre dans un array()

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    $search = array("id" => $_GET['id'], "saison" => $_GET['saison'], "episode" => $_GET['episode']);
     
    $sqlWhere = "";
    $flag = false;
    foreach( $search AS $k => $v ) {
         if( !empty($v) ) {
              $flag = true;
              $sqlWhere .= $k." = ".$v." AND ";
         }
    }
     
    if( $flag ) {
         $sqlWhere = " WHERE ".substr($sqlWhere, 0, -5);
    }
     
    $sql = "SELECT * FROM matable ".$sqlWhere;


    EDIT & NB :
    1] perso, en plus de vérifier que le champ ne soit pas vide, dans mes codes je vérifie si le champ en question est autorisé

    2] j'ai une fonction qui vérifie le contenu de mes variables mais dans ce cas-ci il faudrait utiliser le mysql_real_escape_string() au lieu d'écrire seulement $v

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut
    Je viens de trouver une solution, ça fonctionne parfaitement.

    Par contre je me demande c'est quoi cette histoire de sécuriser les variables

  14. #14
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    C'est simple, si tu ne "cast" (intval) pas t'a variable comme un integer et que tu ne met pas de quote autour de tes champs (e.g. WHERE foo=$bar)

    N'importe qui peut passer quelque chose du genre /?id=NULL OR 1=1[...]

    Donc une injection SQL (faire une reqûete que tu n'as pas du tout souhaitée) et donc peut s'avérer extrêmement dangereux.

    Les quotes autours du champs ne sont pas une valeur sûr non plus si tu ne fais pas de (int) ou intval() dans le cas ou magic_quote_gpc serais désactivés.

    Ce genre de problème est largement documenté

    "Never trust foreign data"

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut
    Ça me fais peur tout ça !
    J'étais complètement ignorant à ce sujet !

    Je fais un bref récapitulatif, tout fonctionne comme je veux, le code final que j'ai c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
    mysql_connect("...", "...", "...");
    mysql_select_db("...");
     
    $retour = mysql_query('select * from episode where id='.intval($id).' OR (saison='.intval($saison).' AND episode='.intval($episode).')');
    while ($donnees = mysql_fetch_array($retour))
    {
    ?>
    Je suis en sécurité comme ça ?

  16. #16
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Oui

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut
    Super !
    Merci PaRa-BoL

    En fait, concrètement, je risque quoi sans les intval ?

    (Je sais je pose trop de questions )

  18. #18
    Membre émérite Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Par défaut
    Je l'ai brièvement expliqué dans mon post précédent.

    En faite si tu ne fais pas de intval et vu que la donnée provient d'un GET (ou POST), une personne malveillante pourrais forger une requete SQL.

    Imagine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $sql = 'SELECT foo FROM bar WHERE id = '.$_GET['id'];
    Si quelqu'un fait quelque chose du genre :
    foobar.com/?id=NULL OR 1=1

    La requête deviendrai donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT foo FROM bar WHERE id = NULL OR 1=1
    Quelque chose que tu n'as pas du tout voulu.

    Le risque se pose souvent à cause l'instruction UNION de SQL qui permet de sélectionner les champs d'une autre tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT x FROM table UNION SELECT y FROM admin
    Grossièrement :
    "y" remplacerai la valeur de "x" s'il n'y a pas de résultat dans "table"

    Si tu essayes d'afficher "x" dans ta page, "y" sera en réalité affiché.
    Cette personne malveillante pourrais donc sélectionner un mot de passe stocké en BDD.

    D'où l'interet du intval qui va "filtrer" la variable passée en GET pour l'a forcer à être un integer et non une instruction SQL mal forgée.

    C'est plus claire ?

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Par défaut
    Tout compris

    Jvais mettre des intval sur les autres pages, même si ya pas de mots de passe dans la BBD, comme ça je suis tranquille

    Thanks

Discussions similaires

  1. [SQL] Recherche avec plusieurs possibilités pour un champ
    Par jeronimo83 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 15/07/2008, 15h27
  2. [C#] Plusieurs LinkButton pour une seule fonction
    Par FunnyDjo dans le forum ASP.NET
    Réponses: 3
    Dernier message: 08/06/2005, 22h01
  3. [Socket] Plusieurs socket pour un client
    Par meda dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 24/05/2005, 17h24
  4. Plusieurs vues pour le même objet
    Par nicolas66 dans le forum OpenGL
    Réponses: 4
    Dernier message: 25/10/2004, 10h27
  5. Réponses: 2
    Dernier message: 05/07/2004, 17h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo