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 :

comment préparer ma requete en POO?


Sujet :

PHP & Base de données

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2008
    Messages
    1 214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 1 214
    Points : 623
    Points
    623
    Par défaut comment préparer ma requete en POO?
    Bonjour a tous
    je souahite crée une class qui fasse des requêtes mais je ne sais pas comment m'y prendre.
    cette class serais alimenter par 2 éléments:
    -l'élément du champs auquels il faudra rechercher
    -l'élément table , c'est un array composer de plusieurs valeur.
    pour essayer de faire un petit test j'ai crée une toutes petit table:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    table Fruit
    ----------------------
    ID_fruit |nom_fruit|
    --------------------
    0         | pêche   |
    1         |pomme   |
    2         |poire      |
    ---------------------
    si je fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $tab_fruit=array('pêche','pomme','poir');
    $find_idruit=new Requete($id_fruit,$tab_fruit);
    cette classe doit m'envoyer
    $reponse=$find_idfruit->getIDfruit()
    echo $reponse; // doit pouvoir m'envoyer 0,1,2

    alors voici ce que je pensais pour ma class requete
    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
     
    class Requete
    {
       private $ID_fruit;
       private $nom_fruit;
       private $fruit;//la table s'appelle fruit;
     
       function public __construct($id_fruit,$tab_fruit)
       {
    //connection PDO
           $reponse=$bdd->query("SELECT $this->id_fruit FROM $this->fruit WHERE ?")
     
       }
     
     
    }
    Ici le ? est un array,comment je peux peut m'y prendre pour que ? qu'il traite l'array??

  2. #2
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Ici le ? est un array,comment je peux peut m'y prendre pour que ? qu'il traite l'array?
    Disons que tu n'indique nulle part sur quels champs seront appliqués les conditions, le ?
    Il faut au moins ça, et peu importe la manière.

    Si les champs sont connus d'avance, qu'il ne serait pas nécessaire de les passer en paramètres, boucler sur le array suffirait.

    Exemple : (simplifié)
    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
     
    $where = '';
    $tot_fruit = count($tab_fruit);
    $i = 1;
    foreach ($tab_fruit as $fruit) {
    	$and = ($i == $tot_fruit) ? '' : 'AND ';
    	$where .= "(champ1 LIKE '%:fruit_1%' OR champ2 LIKE '%:fruit_2%') ".$and;
    	$i++;
    }
    //
    $sql = "SELECT machin FROM table_truc WHERE ".$where;
    $stmt = $bdd->prepare($sql);
    reset($tab_fruit);
    foreach ($tab_fruit as $fruit) {
    	$stmt->bindValue(':fruit_1', $fruit);
    	$stmt->bindValue(':fruit_2', $fruit);
    }
    $stmt->execute();
    Théoriquement, ça devrait le faire.
    Maintenant, il y a surement moyen de faire autrement.

    PDO est un peu plus pénible à utiliser quand on a des requêtes dynamiques, mais, ça reste possible.
    Aussi, et pour profiter pleinement de PDO, il vaut mieux éviter les méthodes PDO::query() ou PDO::exec(), et privilégier les requêtes préparées, pour éviter les injections sql.


    Par contre, le 1er paramètre $idfruit, ça va pas. Au mieux c'est le nom du champ, donc $champFruit.
    Mais ici, le nom du ou des champs sont connus d'avance, de même que la table. Il y a pas lieu de les passer en arguments.

    Puis, vu que le but est de rechercher plusieurs fruits, passer en argument 1 ID de fruit, et bien ça n'a pas de sens.
    Soit on recherche un fruit en passant un ID, soit l'inverse, on passes des critères pour rechercher le ou les fruits.

    C'est les critères qui seraient les seules inconnues, non ?

  3. #3
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2008
    Messages
    1 214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 1 214
    Points : 623
    Points
    623
    Par défaut
    merci de ta réponse runcode
    En effet mon but est de rechercher plusieurs fruits et de trouver son Id pour l'exploiter plus tard
    voici ce que j'avais essayer pourra tu me dire si c'est utile ou c'est pas la penne de crée une class pareille
    d'abord la table le fruit pour connaitre ou l'on doit chercher :
    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
     
    -- Base de données: `lefruit`
    -- --------------------------------------------------------
    -- Structure de la table `fruit`
     
    CREATE TABLE IF NOT EXISTS `fruit` (
      `ID_fruit` int(11) NOT NULL AUTO_INCREMENT,
      `nom_fruit` varchar(10) NOT NULL,
      PRIMARY KEY (`ID_fruit`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
     
    -- Contenu de la table `fruit`
     
    INSERT INTO `fruit` (`ID_fruit`, `nom_fruit`) VALUES
    (1, 'peche'),
    (2, 'pomme'),
    (3, 'poire');
    ensuite j'ai un classe PDO2 pour se connecté:
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    <?php
    class PDO2 extends PDO
    {
      private static $instance;
      /*Obligatoire par héritage de PDO*/
      public function __construct( ) 
      {
      }
     
      /*Singleton*/
      public static function getInstance()
      {
        if(!isset(self::$_instance)) 
        {
          try 
          {
            self::$instance = new PDO('mysql:host=localhost;dbname=lefruit', 'root', '');
          }
     
          catch(PDOException $e) 
          {
           echo $e;
          }
        }
            return self::$instance;
      }
    }
    puis la class requete:
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    <?php
     
    class Requete 
      {
       private $table;
       private $find_fruit=array();//ici un attribut pour les 2 fruits qui nous intéréssent
     
       public function __construct ($find_fruit,$table) 
       {
         $this->table = $table;
         $this->find_fruit=$find_fruit;// écrit comme cecit va t'il lui transmettre à l'attribut car c'est un array()?
       }
     
      public function getReqSelect($find_fruit,$fields) 
      {
       // $fields doit être un array
       $fields = implode(',', $fields);//les différents champs qu'on veut récuperer
       $sql = $bdd->prepare("SELECT $fields FROM $this->table WHERE nom_fruit= ?")
       $sql = $bdd-> execute(array($_GET['$find_fruit']))//ici comment lui dire de récupérer    uniquement 2 ID? et pas tous les ID
     
     
       // Traitement des données de la requête
       $tab=array();
       while ($donne =$sql->fetch()) 
       {
          $tab[] = $donne['ID_fruit'];
       }
      return $tab; // Renvoie le tableau associatif avec les données
     }
    et enfin le script qui execute:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <?php
    include ('class/PDO2.class.php');
    include('class/prep.class.php');//c'est la class requete
    //connection de la base;
    $bdd=PDO2::getInstance(); //connection de la base
    $fruit_cherche=array('peche','pomme');//on veut les ID_fruit des ces 2 fruits
    $ID_fruit=array('ID_fruit','nom_fruit');//on selectionne ces 2 champs
    $donne_id=new Requet($fruit_recherche,$ID_fruit);
    ?>
    en fait ici la class requete va me premettre de faire n'importe qu'elle requete dans la table lefruit, l'idée c'est de passer
    2 élément:

    1-le champ ou l'on veut chercher//c'est peut être imipossible il faut imposer des champs
    2-les fruits qu'on veut savoit leur ID_fruit pour les utlisers par la suite.

    ici mon code ne fonctionne pas à cette erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $sql = $bdd-> execute(array($_GET['$find_fruit']))//ici comment lui dire de récupérer    uniquement 2 ID? et pas tous les ID
    il serait mieux pour moi de mettre dans public fonction getSelect tous ce que tu a écrit à la place de ma requet préparer?

  4. #4
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    //ici comment lui dire de récupérer uniquement 2 ID? et pas tous les ID
    Si tu sais à l'avance que ça doit retourner que 2 lignes, rajoute un LIMIT 2 (suivi d'un ... ORDER BY le_champ ... surement aussi).
    Sinon, faut le passer en argument.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    en fait ici la class requete va me premettre de faire n'importe qu'elle requete dans la table lefruit, l'idée c'est de passer
    2 élément:
     
    1-le champ ou l'on veut chercher//c'est peut être imipossible il faut imposer des champs
    2-les fruits qu'on veut savoit leur ID_fruit pour les utlisers par la suite.
    C'est ça qui m'inquiète un peu.
    Si on réfléchi un peu, et bien s'il faut passer en argument tous les éléments (champs, tables, clause/conditions, nombre de lignes, voir d'autres paramètres encore) il n'y plus grand d'intérêt à créer une classe, voir même aucun.

    L'intérêt d'une classe à mon avis c'est de reporter/déporter des traitements pures afin de réduire la page, que cette dernière s'occupe uniquement de la logique du programme.
    Si tu dois tout passer, donc tout récupérer, voir vérifier avant de les passer en arguments, ça va déboucher sur une usine à gaz dans le corps de la page.
    Bref ... ça n'aurait plus de sens, autant exécuter la requête directement vu que tu auras tous les éléments en main.
    Ca sera plus simple, et surtout plus rapide.

    A mon sens, cette classe n'aurait d'intérêt que pour construire les conditions (les LIKE, OR, AND), le reste serait mieux s'ils sont connus, ou imposés.
    Sinon, aucun intérêt, du moins, je ne vois pas ou il le serait.


    Fais le point la dessus, car créer une classe juste pour créer une classe, ça n'a pas de sens. Il faut qu'il y est un service rendu, un gain, un bénéfice.
    Si dans ton cas tu ne parviens pas à rationaliser tout ça, alors le mode procédural restera le moyen le plus simple, et plus performant en plus.

    Si tu ne sais pas encore quelle serait ton besoin, dans sa globalité, fait ton truc en mode procédural pure, dans un fichier inclus par exemple.
    Exploite les fonctions si nécessaire.
    Bien souvent les chose se dessinent mieux en procédant ainsi.
    (En tout cas, toutes mes classes (sans exception), se sont construites ainsi, au départ c'était purement du procédural, et fonctionnel, je connaissais parfaitement le besoin, et surtout le déroulement).

  5. #5
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2008
    Messages
    1 214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 1 214
    Points : 623
    Points
    623
    Par défaut
    ce script je voulais le testé sur mon moteur, sur un seul champs nom_fruit.c'est vrai que j'ai eu tords de ne pas imposer le champ de recherche.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    A mon sens, cette classe n'aurait d'intérêt que pour construire les conditions (les LIKE, OR, AND),
    si je fait ceci avec ces regex ca va être utliles(1 seul table et 1 seul champs imposer)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT nom_fruit  FROM TABLE WHERE nom_fruit REGEXP "mot qu'il contient";
    j'ai presque fini d'écrire en procédural mon moteur de recherche mais je trouvais que j'avais trop de répetition de requte:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    'SELECT nom_fruit FROM fruit where nom_fruit="abricot"'//test si la saisi exacte est dans la bdd
    'SELECT nom fruit FROM fruit where REGEXP "abricot"'//test si la saisi contient
    'SELECT nom_fuit FROM fruit where REGEXP"^abricot"'//test si la saise commence par
    'SELECT nom_fruit FROM fruit'//saisie  de toute le champ nom_fruit pour le mettre dans un array et pour le comparer avec levensthein
    bien sur lors de la recherche je n'execute pas toute ces requets mais je met des conditions:
    si il trouve pas le mot exacte on recommence par contient
    si il trouve pas le mot contient on recommence par commence par.

    donc j'ai pensé de faire une classe qui regrouperais ces requête pour diminuer ces répértions

  6. #6
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Ne le prend pas mal, mais malgré tous tes exemples, rien ne justifie la création d'une classe.
    Ton besoin se réduit à construire la clause WHERE (avec ou sans REGEXP).
    Une simple fonction suffirait.
    M'enfin, si tu y tiens, pourquoi pas.

    Après, pour la manière de faire, et le problème c'est qu'il peu en avoir 50.
    Si je m'arrête à ton besoin, il se résumerait à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Fruit {
    	protected static $find_fruit = array();//ici un attribut pour les 2 fruits qui nous intéréssent
     
    	public static function getFruits($fruits_array) {
    		// On effectue la requête SQL
    		return $fruits; // Renvoie le tableau associatif avec les données
    	}
    }
     
    // Dans la page :
    $fruits = Fruits::getFruits(array('mangue', 'letchi'));
    Il y aurait même pas besoin de constructeur.
    Puis une simple méthode statique qui permettra de lancer la requête.
    Pour le static, faut voir, mais ici, ça à l'air plutôt intéressant.

    Cependant, ici on conserve toujours un paramètre (un tableau) dans la méthode getFruits().
    Je vois dans ton exemple que c'est un $_GET.
    Vu que $_GET est une super global, tu pourrais alors supprimer ce paramètre, et les obtenir directement, donc de traiter ce tableau (vérifs, boucle, etc ...).
    Un simple : Fruits::getFruits() suffirait.

    Enfin, tout ceci c'est pour exemple, faut voir.


    Pour la requête, un REGEXP, pourquoi pas, mais sauf erreur, on ne profite pas totalement des requêtes préparées (bindValue, ou bindParam).
    Les requêtes préparées dans un tel cas est malheureusement plus compliqué à mettre en oeuvre, c'est l'un des inconvénient de PDO.

  7. #7
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2008
    Messages
    1 214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 1 214
    Points : 623
    Points
    623
    Par défaut
    merci de tous ces tuyaux, je vais resté en procedural.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    on ne profite pas totalement des requêtes préparées (bindValue, ou bindParam).
    Les requêtes préparées dans un tel cas est malheureusement plus compliqué à mettre en oeuvre, c'est l'un des inconvénient de PDO.
    j'avais pensé que si on me demande de faire plus de traitement de donnée à exploiier et a jouter des module en plus j'aurais créer d'autre objet ,mais dit comme tu me l'a dit je vais suivre ton conseil après tous ce n'est qu'un petit moteur de recherche.

    comme je débute dans la PDO et la POO,
    je n'ai pas assez d'expérience et de recul pour savoir quelle est la bonne methode a prendre. donc de savoir qu'on pouvais pas profiter totalement des requête préparer.

    Donc je vais faire du procédural +PDO

    (je venais juste de maîtriser les mysql_fetch,mysql_assoc....qu'il faut déjà ne plus se servir de mysql et de se mettre à la PDO, c'est comme si je recomençais à 0)

  8. #8
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    comme je débute dans la PDO et la POO,
    je n'ai pas assez d'expérience et de recul pour savoir quelle est la bonne methode a prendre.
    Dans ces conditions, si tout ça a un but pédagogique, un apprentissage, rien que ceci peu justifier de le faire, peu importe qui le service rendu ne soit pas totalement présent, ou ayant un très grand intérêt, voir même mal goupillé.
    Au bout, ça restera toujours une expérience.

    Il y a un dicton bien connu qui dit : C'est en forgeant qu'on devient forgeron.

    Un Objet, Fruits ... finalement, pourquoi pas.
    (faut juste éviter que ça fracasse le site).

Discussions similaires

  1. Réponses: 13
    Dernier message: 23/09/2011, 19h24
  2. Réponses: 1
    Dernier message: 17/06/2005, 11h35
  3. [http] comment faire une requete http
    Par Slimer dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 28/07/2004, 12h48
  4. Réponses: 2
    Dernier message: 03/05/2004, 13h13

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