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

Langage PHP Discussion :

conseil sur les requêtes SQL en MVC [PHP 5.3]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    710
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 710
    Par défaut conseil sur les requêtes SQL en MVC
    Bonjour,

    Je suis en train de développer un site en php5 sur le modèle MVC (mon premier) et je suis confronté à un problème que vous aurez certainement déjà rencontré et pour lequel j'espère que vous pourrez me conseiller.

    A certains moment, je dois exécuter cette requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM table

    et à d'autres, je dois exéctuer :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM table WHERE colonne1 = 'param1' AND colonne2 = 'param2' AND colonne3 = 'param3'

    Je me dis qu'une seule méthode devrait pouvoir me remonter les résultats d'une ou de l'autre requête et que je n'ai pas besoin de faire 2 méthodes (getAll() et getSpecific()). Mon idée est donc de faire un méthode avec un tableau de paramètre qui permettra de générer la requête adéquate (complète ou restreinte). Mes interrogations sont les suivantes dans la mesure où les éléments propres à la bd doivent rester dans la couche modèle, je ne vais pas utiliser les noms de colonne dans le controller (dans le tableau de paramètre) ! Dans ce cas, le lien entre mes valeurs de restrictions (définies dans mon controller) et les colonnes de ma table (utilisées dans le model) ? Evidemment, je pourrai faire le lien entre les index de mon tableau et les nom de colonnes, mais je ne trouve pas cela très fin ! Plus généralement, si ne dois pas utiliser les noms de mes colonnes ailleurs que dans les model, comment faire, lorsqu'un model renvoi un tableau de résultats, pour les utiliser dans mon controller correspondant, je vais être obligé de faire $r['nomcolonne'], non ?

    merci de vos lumières !

  2. #2
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    A un moment ou à un autre il faudra bien lier tes données aux besoins d'un traitement.
    Pour ne pas utiliser les noms des colonnes tu peux utiliser des alias à la place. Il est tout à fait possible que l'alias corresponde au nom de la colonne mais ce n'est pas nécessaire.

    L'intérêt c'est que tu peux très bien avoir ce genre de requête :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT a.nom, b.nom FROM a INNER JOIN b...
    dans ce cas, tu devras avoir des alias pour repérer tes colonnes
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT a.nom AS nom_parent, b.nom AS nom_enfant FROM a INNER JOIN b...
    Vu que tu ne peux pas présupposer des ressources DB à ta disposition, il est préférable d'uniformiser le tout en utilisant toujours des alias et bâtir de système de génération auto SQL sur cette approche.

    J'ai codé un système de cet acabit (un exemple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $data = Membre::select(ExecParams $params);
    La fonction select() expose en commentaire une liste d'alias et attend une classe de paramétrage, en fonction de son contenu, elle est capable de valider les paramètres un à un et d'écrire un SQL valide ou si la ressource SQL est trop complexe (style code SQL monstrueux, hyper optimisé) de remplir les blancs sans altérer le code SQL.

  3. #3
    Membre éclairé Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    710
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 710
    Par défaut
    Merci de ton retour.
    Selon toi, les alias de colonnes sont donc le lien entre les controllers et les models ?

  4. #4
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Oui, c'est comme ça que je le vois.
    Tu conserves la flexibilité du côté du modèle d'organiser tes ressources comme tu l'entends et du côté du contrôleur tu n'exposes rien d'autre qui soit différent d'un simple paramétrage du modèle -> situation idéale

  5. #5
    Membre éclairé Avatar de grinder59
    Inscrit en
    Septembre 2005
    Messages
    710
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 710
    Par défaut
    Humm, j'essaie de prendre un cas concret, histoire de voir si j'ai bien compris :

    voici une requête :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT
        t1.col1
        t2.col2
        t3.col3
    FROM
        tab1 t1 INNER JOIN
        tab2 t2 ON t1.id = t2.id LEFT JOIN
        tab3 t3 ON t2.id = t3.id
    GROUP BY
        col1

    Cette requête permet de remonter toutes les données. Elle est exécutée par l'appel : maclasse::getData();

    Dès lors que je ne veux récupérer qu'une partie des données, j'exécute la même requête mais avec la clause WHERE suivante :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    WHERE
        col1 > 10 AND
        col2 = 300

    Ayant déjà une requête qui remonte toutes les infos, le but est la réutiliser - en l'affinant - pour ne récupérer que la partie souhaitée des données.

    Je paramètre donc un tableau dans mon controller avec de transmettre les valeurs WHERE a mon model :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $param[alias_colonne1] = '> 10';
    $param[alias_colonne2] = '= 300';
     
    // pour appeler le model de la façon suivante :
    maclasse::getData($param);
    Dans 2 constantes, j'aurai déclaré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    define ('alias_colonne1', 'col1');
    define ('alias_colonne2', 'col2');
    et dans la fonction du model, je manipulerai le tableau de paramètre de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach($param as $key => $value){
       $query .= $key.$value;
    }
    Est-ce que sur le principe j'ai bon ? Par contre la fonction de conversion du tableau de param en WHERE doit être chiadée parce que pour l'instant elle en prend pas en compte un truc du type :
    col1 > 10 AND (col2 < 20 OR col3 > 50) !

  6. #6
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Tes alias devraient apparaître ici
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT
        t1.col1 AS alias_colonne1,
        t2.col2 AS alias_colonne2,
        t3.col3 AS alias_colonne3
    FROM
    Tes alias n'ont strictement rien à voir avec des constantes globales (define(...)).

    Ensuite il est tout à fait possible de définir le signe de comparaison dans la valeur du paramètre (comme tu le fais '> 10'), sauf que cela va du coup légèrement gagner en complexité dans le traitement : tu vas devoir extraire le signe pour ensuite valider si la valeur de la variable correspond au type attendu par la colonne... Parce qu'il est hors de question dans un système de génération automatique de SQL de ne pas valider les données avant l'exécution de la requête.

    Et pour les clauses très complexes comme : col1 > 10 AND (col2 < 20 OR col3 > 50), ben là il y a pas de mystère : soit tu codes un parseur soit tu codes un système où la clause est créée étape par étape permettant ainsi la validation de chacune des valeurs du critère.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 22/08/2014, 15h57
  2. [Débutant] Question sur les requêtes SQL
    Par Genyuumaru dans le forum ASP.NET MVC
    Réponses: 4
    Dernier message: 08/10/2012, 08h43
  3. Réponses: 4
    Dernier message: 21/04/2012, 12h56
  4. [MySQL] [POO] Sécurité sur les requêtes SQL
    Par Sh4dow49 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 24/10/2008, 10h51

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