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 :

Factorisation des requêtes PDO [PDO]


Sujet :

PHP & Base de données

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Mai 2015
    Messages : 20
    Points : 24
    Points
    24
    Par défaut Factorisation des requêtes PDO
    Bonsoir,

    Je viens de terminer ma classe ModelePDO et, n'étant qu'un débutant, j'aimerais avoir vos avis sur mon code et les améliorations possibles ou toute autres remarques.

    Le but de cette classe est d'éviter d'avoir à réécrire à chaque fois mes requêtes du début à la fin.

    Trève de blabla, voici le code :

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
     
     
    class ModelePDO {
     
     
        private static $serveur = MysqlConfig::SERVEUR;
        private static $base = MysqlConfig::BASE;
        private static $utilisateur = MysqlConfig::UTILISATEUR;
        private static $passe = MysqlConfig::MOT_DE_PASSE;
     
     
        private static $pdoCnxBase = null;
        private static $pdoStResults = null;
        private static $requete = ""; 
        private static $resultat = null;
     
     
     
     
        /**
         * Permet de se connecter à la base de données
         */
     
        private static function seConnecter(){
            if(!isset(self::$pdoCnxbase)) { //S'il n'y a pas encore eu de connexion
                try {
                    self::$pdoCnxBase = new PDO('mysql:host=' . self::$serveur . ';dbname=' . self::$base, self::$utilisateur, self::$passe);
                    self::$pdoCnxBase->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                    self::$pdoCnxBase->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
                    self::$pdoCnxBase->query("SET CHARACTER SET utf8");
     
                } catch (Exception $ex) {
                       echo 'Erreur : ' . $ex->getMessage() . '<br />'; //recuperation du message d'erreur 
                       echo 'Code : ' .$ex->getCode(); //recupeation du code d'erreur
                }
            }
        }
     
        /**
         * Deconnection de la base de donnée
         */
        private static function seDeconnecter(){
            self::$pdoCnxBase = null;
        }
     
     
        /**
         * Construit le début de la requête select suivant la variable $table passer en parametre
         * @param string/array $selection colonnes à selectionner
         * @return string
         */
        private static function constructSelection($selection, $typeSelection){
     
            $string = $typeSelection;
     
            if (gettype($selection) == 'array') {
     
                foreach ($selection as $value) {
     
                   $string .= $value . ', ';
     
                }
     
                $string = rtrim($string, ', ');
                $selection = $string;
            }
            else {
     
                $string .= $selection;
            }
     
            return $string;
     
        }
        /**
         * Construit la clause FROM de la requête suivant la variable $from passer en paramètre
         * @param string/array $from Table qui contiennent les colonnes à selectionner
         * @return string 
         */
        private static function constructFROM($from){
     
            $string = "FROM ";
     
            if (gettype($from) == 'array') {
     
                foreach ($from as $value) {
     
                   $string .= $value . ', ';
     
                }
     
                $string = rtrim($string, ', ');
     
            } else {
     
                $string .= $from;
            }
     
            return $string;
        }
     
     
        private static function constructWHERE($condition){
     
            $string = " WHERE ";
     
            if (gettype($condition) == 'array') {
     
                foreach ($condition as $value) {
     
                   $string .= $value . ' AND ';
     
                }
     
                $string = rtrim($string, ' AND ');
     
            } else {
     
                $string .= $condition;
            }
     
            return $string;
        }
     
        private static function constructSET($set){
     
            $string = " SET ";
     
            if (gettype($set) == 'array') {
     
                foreach ($set as $value) {
     
                   $string .= $value . ', ';
     
                }
     
                $string = rtrim($string, ', ');
     
            } else {
     
                $string .= $set;
            }
     
            return $string;
     
        }
     
        private static function constructBindValues($string, $values){
     
            $bindvalues = "";
            preg_match_all("#:[a-zA-Z]\w+#", $string, $bindvalues);
     
            switch (gettype($values)) {
     
                case "array":{
     
                    for ($x = 0; $x < count($bindvalues[0]); $x++) {
     
                        self::$pdoStResults->bindvalue($bindvalues[0][$x], $values[$x]);
                    }
     
                    break;
                }
     
                case "string":{
     
                    self::$pdoStResults->bindvalue($bindvalues[0][0], $values);
                    break;
                }
            }    
        }
     
     
     
        /**
         * Soumet une requete select au SGBD 
         * @param string/array  $selection   Champ(s) à selectionner
         * @param string/array  $from        Table(s) contenant le(s) champ(s) à selectionner
         * @param boolean       $fetchAll    Stipule la forme de retour : 1 pour FetchAll, 0 pour Fetch
         * @param string/array  $condition   Condition(s) de la requête (WHERE) (Optionnel)
         * @param string/array  $valeurs     Valeur(s) que doit(vent) remplir la (les) condition(s)  (format bindValue) (Optionnel)
         * exemple d'appel : 
         * @return array
         */
        protected static function selectTuple($selection, $from, $fetchAll,$condition = null, $valeurs = null){
     
            //construction 
            $selection = self::constructSelection($selection, "SELECT ");
            $from = self::constructFROM($from);
     
            //construction des conditions si necessaire
            if ($condition <> null){$where = self::constructWHERE($condition);}
     
            //concaténation des trois parties
            self::$requete = $selection . ' ' . $from . ' ' . $where;
     
            //connexion
            self::seConnecter();
     
            //preparation 
            self::$pdoStResults = self::$pdoCnxBase->prepare(self::$requete);
     
            //affectation des bindValues si necessaire
            if ($valeurs <> null){self::constructBindValues(self::$requete, $valeurs);}
     
            //execution
            self::$pdoStResults->execute();
     
            //suivant le param $fetchAll on configure le mode de sortie
            if ($fetchAll) {
     
                self::$resultat = self::$pdoStResults->fetchAll();
     
            } else {
     
                self::$resultat = self::$pdoStResults->fetch();
            }
     
            //deconnexion
            self::$pdoStResults->closeCursor();
            self::seDeconnecter();
     
            //retour du résultat de la requete
            return self::$resultat;
     
        }    
     
        protected static function DeleteTuple($from, $condition = null, $valeurs = null){
     
            $selection = "DELETE";
            $from = self::constructFROM($from);
     
            //construction des conditions si necessaire
            if ($condition <> null){$where = self::constructWHERE($condition);}
     
            self::$requete = $selection . ' ' . $from . ' ' . $where;
     
            //connexion
            self::seConnecter();
     
            //preparation 
            self::$pdoStResults = self::$pdoCnxBase->prepare(self::$requete);
     
            //affectation des bindValues si necessaire
            if ($valeurs <> null){self::constructBindValues(self::$requete, $valeurs);}
     
            //execution
            self::$pdoStResults->execute();
     
            //deconnexion
            self::$pdoStResults->closeCursor();
            self::seDeconnecter();
     
        }
     
        protected static function UpdateTuple($selection, $set, $condition, $valeurs){
     
            $selection = self::constructSelection($selection, 'UPDATE ');
     
            $set = self::constructSET($set);
     
            if($condition <> null){$where = self::constructWHERE($condition);}
     
            self::$requete = $selection . ' ' . $set . ' ' . $where;
     
            //connexion
            self::seConnecter();
     
            //preparation 
            self::$pdoStResults = self::$pdoCnxBase->prepare(self::$requete);
     
     
            //affectation des bindValues si necessaire
            if ($valeurs <> null){self::constructBindValues(self::$requete, $valeurs);}
     
            //execution
            self::$pdoStResults->execute();
     
           //deconnexion
            self::$pdoStResults->closeCursor();
            self::seDeconnecter();
        }
     
        protected static function InsertTuple($selection, $nomvaleurs,$valeurs){
     
            $selection =  "INSERT INTO $selection VALUES (" ;
     
            if (gettype($valeurs) == 'array') {
     
                foreach ($nomvaleurs as $value) {
     
                   $string .= $value . ', ';
     
                }
     
                $string = rtrim($string, ', ');
     
            } else {
     
                $string .= $nomvaleurs;
            }
     
            self::$requete = $selection . $string . ')';
     
     
             //connexion
            self::seConnecter();
     
            //preparation 
            self::$pdoStResults = self::$pdoCnxBase->prepare(self::$requete);
     
     
            //affectation des bindValues si necessaire
            if ($valeurs <> null){self::constructBindValues(self::$requete, $valeurs);}
     
            //execution
            self::$pdoStResults->execute();
     
           //deconnexion
            self::$pdoStResults->closeCursor();
            self::seDeconnecter();
     
        }
    }
    Et voici quelques exemples d'utilisation de la classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return ModelePDO::selectTuple('*', 'categorie', 1);
    Pour un "SELECT * FROM categorie"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            $from = ['PRODUIT', 'categorie'];
            $condition = ['idCategorie = idCat', 'LibelleCategorie = :LibelleCategorie'];
            $valeurs = $libelle;
            return ModelePDO::selectTuple("*", $from, 1, $condition, $valeurs);
    Pour un "SELECT * FROM PRODUIT p, categorie c WHERE c.idCategorie = p.idCat AND LibelleCategorie = $libelle"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            $set = ['Civilite = :civilite', 'nom = :nom', 'prenom = :prenom', 'mail = :mail', 'adRue = :rue', ' adCP = :cp', 'adVille = :ville'];
            $where = "id = :id";
            $valeurs = [$civilite, $nom, $prenom, $mail, $rue, $cp, $ville, $id];
            ModelePDO::UpdateTuple("membre", $set, $where, $valeurs);
    Pour un "UPDATE membre SET Civilite = :civilite, nom = :nom, prenom = :prenom, mail = :mail, adRue = :rue, adCP = :cp, adVille = :ville WHERE id= :id"


    Ainsi de suite pour DeleteTuple() et InsertTuple()

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    En tant qu'utilisateur de ta classe, est-ce que tu penses qu'une requête avec ta classe est plus simple à lire qu'une requête PDO ordinaire? Si tu relis ton code dans six mois, est-ce que tu comprendras tout de suite ce que le code veut dire, sans regarder les méthodes de ta classe pour savoir comment il fait?

    Ecrire du SQL présente un avantage: c'est un langage universel, donc compréhensible par tous. Il faut des bonnes raisons pour vouloir s'en passer. L'une de ces raisons est de garder une programmation 100% orientée objet, mais si c'est le cas je pense que tu es encore à mi-chemin. Tu as fait les briques, mais il faut encore les monter. Tes classes sont encore à très bas niveau donc ne présentent pas suffisamment d'intérêt pour l'instant.

    Fais une recherche sur les QueryBuilders de Doctrine, Laravel, Zend ou Cake PHP 3 pour voir les syntaxes et les formats des classes de haut niveau, qui sont beaucoup plus faciles à utiliser et à comprendre. Si je lis ton code, je ne peux pas comprendre ce qu'il fait sans fouiller le contenu des méthodes de ta classe ModelePDO.

    Tu devrais pouvoir faire tes propres query builders à partir de ta classe actuelle (sans forcément imiter la mécanique interne de ces classes, qui sont beaucoup trop compliquées pour quelqu'un qui apprend).

    Autre remarque: pourquoi vouloir à tout prix faire du tout statique? Tu ne fais plus de l'objet dans ce cas, tes classes sont justes des "enveloppes" pour des fonctions ordinaires.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Mai 2015
    Messages : 20
    Points : 24
    Points
    24
    Par défaut
    Salut,

    Premièrement merci d'avoir pris le temps de me répondre !

    Citation Envoyé par Tsilefy Voir le message
    En tant qu'utilisateur de ta classe, est-ce que tu penses qu'une requête avec ta classe est plus simple à lire qu'une requête PDO ordinaire? Si tu relis ton code dans six mois, est-ce que tu comprendras tout de suite ce que le code veut dire, sans regarder les méthodes de ta classe pour savoir comment il fait?
    Effectivement il est plus difficile de lire la requête, et j'espère que grâce à la doc je m'y retrouverais assez facilement..

    Ecrire du SQL présente un avantage: c'est un langage universel, donc compréhensible par tous. Il faut des bonnes raisons pour vouloir s'en passer. L'une de ces raisons est de garder une programmation 100% orientée objet, mais si c'est le cas je pense que tu es encore à mi-chemin. Tu as fait les briques, mais il faut encore les monter. Tes classes sont encore à très bas niveau donc ne présentent pas suffisamment d'intérêt pour l'instant.

    Fais une recherche sur les QueryBuilders de Doctrine, Laravel, Zend ou Cake PHP 3 pour voir les syntaxes et les formats des classes de haut niveau, qui sont beaucoup plus faciles à utiliser et à comprendre. Si je lis ton code, je ne peux pas comprendre ce qu'il fait sans fouiller le contenu des méthodes de ta classe ModelePDO.

    Tu devrais pouvoir faire tes propres query builders à partir de ta classe actuelle (sans forcément imiter la mécanique interne de ces classes, qui sont beaucoup trop compliquées pour quelqu'un qui apprend).
    OK je vais donc regarder de ce côté là !

    Autre remarque: pourquoi vouloir à tout prix faire du tout statique? Tu ne fais plus de l'objet dans ce cas, tes classes sont justes des "enveloppes" pour des fonctions ordinaires.
    Ce que tu veux dire c'est que je devrait créer un objet requête et m'en servir pour effectuer mes requêtes ?

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Citation Envoyé par momolasd Voir le message
    Ce que tu veux dire c'est que je devrait créer un objet requête et m'en servir pour effectuer mes requêtes ?
    Oui, parce qu'ainsi tu pourras bénéficier plus tard des avantages des "vrais" objets, comme les passer ton objet à d'autres objets ou pouvoir les tester (est-ce que tu as déjà regardé comment on fait les tests unitaires, et pourquoi on les fait?), etc...

    L'utilisation de méthodes et propriétés non-statiques devrait être la règle, et l'utilisation de statiques une exception lorsqu'on veut vraiment un comportement statique.

    Puisqu'on est dans le refactoring, il est peut-être aussi préférable oplus tard de séparer ta grosse classe en plusieurs classes plus petites. Par exemple, je vois des méthodes qui utilisent une connexion (seConnecter(), DeleteTuple() etc...) et d'autres qui se contentent de transformer un string ou un array en string (constructSelection()). Il est donc possible d'isoler ces dernières méthodes dans une classe séparée. Plus une classe est courte et concentrée sur une seule tâche, plus c'est facile de l'utiliser et de comprendre ce qu'elle fait. Mais c'est pour plus tard, et à toi de voir si tu veux le faire.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Mai 2015
    Messages : 20
    Points : 24
    Points
    24
    Par défaut
    Bonjour !



    Citation Envoyé par Tsilefy Voir le message
    Oui, parce qu'ainsi tu pourras bénéficier plus tard des avantages des "vrais" objets, comme les passer ton objet à d'autres objets ou pouvoir les tester (est-ce que tu as déjà regardé comment on fait les tests unitaires, et pourquoi on les fait?), etc...
    Tests unitaires ? Non jamais entendu parler !

    Citation Envoyé par Tsilefy Voir le message
    L'utilisation de méthodes et propriétés non-statiques devrait être la règle, et l'utilisation de statiques une exception lorsqu'on veut vraiment un comportement statique.

    Puisqu'on est dans le refactoring, il est peut-être aussi préférable oplus tard de séparer ta grosse classe en plusieurs classes plus petites. Par exemple, je vois des méthodes qui utilisent une connexion (seConnecter(), DeleteTuple() etc...) et d'autres qui se contentent de transformer un string ou un array en string (constructSelection()). Il est donc possible d'isoler ces dernières méthodes dans une classe séparée. Plus une classe est courte et concentrée sur une seule tâche, plus c'est facile de l'utiliser et de comprendre ce qu'elle fait. Mais c'est pour plus tard, et à toi de voir si tu veux le faire.
    J'ai donc retapé mon code, en objet cette fois :

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
     
    <?php
     
     
    class Requete {
     
        // <editor-fold defaultstate="collapsed" desc="Champs">
        // definition des champs
        private $_requete = "inconnu";
        private $_pdoStResults = "inconnu";
        private $_bdd = array();
        private $_BindValue = array();
        private $_tabRequete = array();
        private $_pdoCnxBase = null;
     
        // </editor-fold>
     
     
        // <editor-fold defaultstate="collapsed" desc="Méthodes">
        // definition des Méthodes 
     
        /**
         * Méthode magique GET
         */
        public function __get($propriete) {
     
            switch ($propriete) {
     
                case "bdd" : return $this->_bdd; break;
                case "BindValue" : return $this->_BindValue; break;
                case "requete" : return $this->_requete; break;
                case "pdoStResults" : return $this->_pdoStResults; break;
                case "tabCondition" : return $this->_tabRequete[2]; break;
                case "tabFrom" : return $this->_tabRequete[1]; break;
                case "tabSelect" : return $this->_tabRequete[0]; break;
                case "pdoCnxBase" : return $this->_pdoCnxBase; break;
     
            }
        }
     
        /**
         * Méthode magique SET
         */
        public function __set($propriete, $value) {
     
            switch ($propriete) {
     
                case "bdd" : $this->_bdd = $value;  break;
                case "BindValueName" : $this->_BindValue[0][] = $value; break;
                case "BindValue" : $this->_BindValue[1][] = $value; break;
                case "tabCondition" : $this->_tabRequete[2][] = $value; break;
                case "tabSelect" : $this->_tabRequete[0][] = $value; break;
                case "tabFrom" : $this->_tabRequete[1][] = $value; break;
                case "requete" : $this->_requete = $value; break;
                case "pdoStResults" : $this->_pdoStResults = $value; break;
                case "pdoCnxBase" : $this->_pdoCnxBase = $value; break;
                default : throw new Exception("propriétré inconnu : $propriete");
             }
        } 
     
         /**
         * Permet de se connecter à la base de données
         */
     
        private function seConnecter(){
     
     
            if(($this->pdoCnxBase == null)) { //S'il n'y a pas encore eu de connexion
     
                try {
     
                    $this->pdoCnxBase = new PDO('mysql:host=' . $this->bdd[0] . ';dbname=' . $this->bdd[1], $this->bdd[2], $this->bdd[3]);
                    $this->pdoCnxBase->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                    $this->pdoCnxBase->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
                    $this->pdoCnxBase->query("SET CHARACTER SET utf8");
     
                } catch (Exception $ex) {
                       echo 'Erreur : ' . $ex->getMessage() . '<br />'; //recuperation du message d'erreur 
                       echo 'Code : ' .$ex->getCode(); //recuperation du code d'erreur
                }
            }
        }
     
        /**
         * Deconnection de la base de donnée
         */
        private function seDeconnecter(){
            $this->pdoCnxBase = null;
        }
     
        /**
         * Construction de la requête 
         */
        private function constructRequete(){
     
            $select = " SELECT ";
     
            foreach ($this->tabSelect as $colonne) {
     
                   $select .= $colonne . ",";
     
            }
     
            $select = rtrim($select, ',');
     
            $from = " FROM ";
     
            foreach ($this->tabFrom as $table) {
     
                   $from .= $table . ",";
     
            }
     
            $from = rtrim($from, ',');
     
            $where = " WHERE ";
     
            foreach ($this->tabCondition as $condition) {
     
                   $where .= $condition . "= :" . $condition . ' AND ';
     
            }
     
            $where = rtrim($where, ' AND ');
     
            $this->requete = "$select $from $where";
     
        }
     
        /**
         * Définition des bindValues
         * @param string $valueName
         * @param string $value
         */
        public function setBindValue($valueName, $value){
     
            $this->BindValueName = ':'.$valueName;
            $this->BindValue = $value;
            var_dump($this->getBindValue());
        }
     
        /**
         * Construction des BindValues
         * @param array $tab
         */
        private function constructBindValues($tab){
     
            for ($x = 0; $x < count($tab[0]); $x++) {
     
                var_dump($tab);
                $this->pdoStResults->bindvalue($tab[0][$x], $tab[1][$x]);
            }
        }
     
        /**
         * définition du select
         * @param array $selection
         */
        public function select($selection){
     
            $this->tabSelect = $selection;
        }
     
        /**
         * définition de l'update
         * @param string $udpate
         */
        public function update($udpate){
     
     
        }
     
        /**
         * définition des colonnes à setter
         * @param array $set
         */
        public function set($set){
     
     
        }
     
        /**
         * définition du from
         * @param string $from
         */
        public function from($from){
     
            $this->tabFrom = $from;
        }
     
        /**
         * définition du where
         * @param string $where
         */
        public function where($where, $bindvalue = null){
     
            $this->tabCondition = $where;
            if ($bindvalue <> null){
     
                $this->setBindValue($where, $bindvalue);
            }
        }
     
        /**
         * execute la requête
         */
        public function execute(){
     
            //construction de la requete
            $this->constructRequete();
            //connexion
            $this->seConnecter();
            //préparation de la requete
            $this->pdoStResults = $this->pdoCnxBase->prepare($this->requete);
            //attribution des bindvalues si necessaires
            if($this->BindValue <> null){$this->constructBindValues($this->BindValue);}
            //execution
            $this->pdoStResults->execute();
            //deconnexion
            $this->seDeconnecter();
     
        }
     
        public function fetchAll(){
     
            return $this->pdoStResults->fetchAll();
        }
     
        public function fetch(){
     
            return $this->pdoStResults->fetch();
        }
     
        /**
         * Retourne la requête
         * @return string
         */
        public function getQuery() {
     
            return $this->requete;
        }
     
         /**
         * Retourne le tableau des bindValues
         */
        public function getBindValue(){
     
            return $this->BindValue;
        }
     
        // </editor-fold>
     
     
     
     
        // <editor-fold defaultstate="collapsed" desc="Constructeur">
        // Constructeur
     
        /**
         * Construction de l'objet Requête
         * @param array $bdd Doit contenir les infos de connexion à la bdd dans l'ordre suivant : Serveur, Base, user, passe.
         */
        public function __construct(array $bdd) {
     
            $this->bdd = $bdd;
     
        }
     
        // </editor-fold>
     
    }

    Et voici un exemple d'appel pour le select :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    $bdd = [MysqlConfig::SERVEUR, MysqlConfig::BASE, MysqlConfig::UTILISATEUR, MysqlConfig::MOT_DE_PASSE];
    $sql = new Requete($bdd);
     
    $sql->select('*');
    $sql->from("PRODUIT");
    $sql->from("categorie");
    $sql->where("idCategorie", "1");
    $sql->where("LibelleCategorie", "PORTABLES");
    $sql->execute();
     
    $test = $sql->fetchAll();
    var_dump($test);
    Avant de coder le reste (insert, delete, update..), j'attend ton ressentit

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Citation Envoyé par momolasd Voir le message
    Tests unitaires ? Non jamais entendu parler !
    Va voir Google :-) Tu n'en auras peut-être pas besoin dans l'immédiat, mais ça ne fait pas de mal de savoir ce que c'est et à quoi ça sert.

    Citation Envoyé par momolasd Voir le message
    Avant de coder le reste (insert, delete, update..), j'attend ton ressentit
    Ce n'est pas mon ressenti qui compte, c'est le tien!

    Qu'est-ce qui est plus facile, plus agréable à lire et à comprendre?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $from = ['PRODUIT', 'categorie'];
    $condition = ['idCategorie = idCat', 'LibelleCategorie = :LibelleCategorie'];
    $valeurs = $libelle;
    $test = ModelePDO::selectTuple("*", $from, 1, $condition, $valeurs);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    $sql = new Requete($bdd);
     
    $sql->select('*');
    $sql->from("PRODUIT");
    $sql->from("categorie");
    $sql->where("idCategorie", "1");
    $sql->where("LibelleCategorie", "PORTABLES");
    $sql->execute();
     
    $test = $sql->fetchAll();
    Le premier, tu as des variales qui prennent des tableaux, que tu donnes ensuite à une méthode. C'est compliqué à comprendre.
    Le second, on a l'impression que tu t'adresses directement à la base de données. Toute personne parlant anglais pourrait comprendre ce code, même si elle sait pas programmer. C'st plus long certes (mais la qualité d'un programme ne se décide pas en termes de lignes de code), mais plus lisible. Si tu relis ces deux codes dans un an, sans y avoir touché et en ayant travaillé sur d'autres codes, tu comprendras tout de suite le 2e, et ton futur toi t'en remerciera.
    Et pour plus de lisibilité tu peux utiliser des "fluent methods" pour avoir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    $requete = new Requete($bdd)
           ->select('*')
           ->from("PRODUIT")
           ->from("categorie")
           ->where("idCategorie", "1")
           ->where("LibelleCategorie", "PORTABLES")
           ->execute();
     
    $test = $requete->fetchAll();
    Pour cela, il faut légèrement modifier ton code et terminer les méthodes select, from, where, execute etc... avec return $this pour que tu récupères l'objet à chaque fois afin de pouvoir enchaîner directement la méthode suivante;
    Je pense que ça améliore la lisibilité encore plus (pas de répétition, on a l'impression d'une progression plus logique). Attention, il ne faut pas abuser de la technique des fluent method. Ne commence pas à ajouter return $this partout dans ton code, elle n'est conseillée que dans des cas comme ici (un querybuilder, ou ce qu'on appelle un DSL avec une fluent interface). Ailleurs, elle peut au contraire rendre le code plus difficile à comprendre.

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

Discussions similaires

  1. optimisation des requêtes
    Par yech dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 21/09/2004, 19h03
  2. Recherche ibrairie pour éxécuter des requêtes SQL via C++
    Par daemon dans le forum Choisir un environnement de développement
    Réponses: 5
    Dernier message: 14/06/2004, 10h28
  3. log des requêtes sous sybase 10
    Par VsMetal dans le forum Sybase
    Réponses: 3
    Dernier message: 03/05/2004, 14h09
  4. Fichier log des requêtes d'une bdd
    Par Sub0 dans le forum Administration
    Réponses: 4
    Dernier message: 22/03/2004, 14h12
  5. formatage des requêtes sous psql
    Par Bouboubou dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 03/02/2004, 11h10

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