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

Contribuez / Téléchargez Sources et Outils PHP Discussion :

[PDO] Un singleton rapide et efficace


Sujet :

Contribuez / Téléchargez Sources et Outils PHP

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 20
    Points : 18
    Points
    18
    Par défaut [PDO] Un singleton rapide et efficace
    Bonjour,

    Pour un accès rapide aux données MySQL via PDO, je vous propose ma petite contribution suivante :

    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
     
    <?php
     
    /**
     * PDOSingleton class 
     * @author Beno!t POLASZEK - 2013
     */
    class PDOSingleton {
     
        /**
         * Current Instance 
         */
        private static $instance;
     
        /**
         * PDO object Instance 
         */
        private        $PDOInstance = null;
     
        /**
         * Constructor 
         * 
         * @param string $dsn : Data source name
         * @param string $username : User Name
         * @param string $password : User Password
         * @param string $driver_options : PDO Specific options
         * @return PDO PDOInstance
         */
        private function __construct($dsn, $username = null, $password = null, $driver_options = null) {            
            $this->PDOInstance    =    new PDO($dsn, $username, $password, $driver_options);            
        }        
     
        /**
         * Singleton call 
         * 
         * @param string $dsn : Data source name
         * @param string $username : User Name
         * @param string $password : User Password
         * @param string $driver_options : PDO Specific options
         * @return PDO PDOInstance
         */
        public static function Cnx($dsn = null, $username = null, $password = null, $driver_options = null) {
            if (is_null(self::$instance))
                self::$instance    =    new self($dsn, $username, $password, $driver_options);
     
            return self::$instance;
        }
     
        /**
         * Prepares a SQL Query and executes it 
         * 
         * @param string $SqlString : SQL Query
         * @param array $SqlParams : PDO Params to bind
         * @return PDOStatement Stmt
         */
        public function Sql($SqlString, array $SqlParams = array()) {
     
            $Stmt        =    self::Cnx()->Prepare($SqlString);
     
            foreach ($SqlParams AS $Key => $Value)
                $Stmt    ->    BindValue(':' . $Key, $Value, self::PDOType($Value));
     
            $Stmt->Execute();
     
            return $Stmt;
     
        }        
     
        /**
         * SqlArray executes Query : returns the whole result set
         *  
         * @param string $SqlString : SQL Query
         * @param array $SqlParams : PDO Params to bind
         * @return Array
         */
        public function SqlArray($SqlString, array $SqlParams = array()) {
            return $this->Sql($SqlString, $SqlParams)->FetchAll(PDO::FETCH_ASSOC);
        }
     
        /**
         * SqlLine executes Query : returns the 1st row of your result set
         *  
         * @param string $SqlString : SQL Query
         * @param array $SqlParams : PDO Params to bind
         * @return Array
         */
        public function SqlLine($SqlString, array $SqlParams = array()) {
            return $this->Sql($SqlString, $SqlParams)->Fetch(PDO::FETCH_ASSOC);
        }
     
        /**
         * SqlValues executes Query : returns the 1st column of your result set
         *  
         * @param string $SqlString : SQL Query
         * @param array $SqlParams : PDO Params to bind
         * @return Array
         */
        public function SqlValues($SqlString, array $SqlParams = array()) {
            return $this->Sql($SqlString, $SqlParams)->FetchAll(PDO::FETCH_COLUMN);
        }
     
        /**
         * SqlValue executes Query : returns the 1st cell of your result set
         *  
         * @param string $SqlString : SQL Query
         * @param array $SqlParams : PDO Params to bind
         * @return String
         */
        public function SqlValue($SqlString, array $SqlParams = array()) {
            return $this->Sql($SqlString, $SqlParams)->Fetch(PDO::FETCH_COLUMN);
        }
     
        /**
         * Magic call - PDO methods 
         */
        public function __call($Method, $Args) {
     
            $Args    =    implode(', ', $Args);
     
            if ($Args)
                return $this->PDOInstance->$Method($Args);
            else
                return $this->PDOInstance->$Method();
        }
     
        /**
         * PDO Automatic type binding 
         * 
         * @param mixed var
         * @return PDO const 
         */
        private static function PDOType($Var) {
     
            switch (gettype($Var)) :
     
                case 'int'      :
                case 'integer'  :
                    return PDO::PARAM_INT;
     
                case 'double'   :
                case 'float'    :
                    return PDO::PARAM_STR;
     
                case 'bool'     :
                case 'boolean'  :
                    return PDO::PARAM_BOOL;
     
                case 'null'     :
                    return PDO::PARAM_NULL;
     
                default         :
                    return PDO::PARAM_STR;
     
            endswitch;
     
        }
     
    }
    La classe permet de typer automatiquement les paramètres PDO en fonction du cast PHP, et fournit des méthodes d'accès rapides aux données : SqlArray pour récupérer un tableau multidimensionnel, SqlLine pour une ligne, SqlValues pour une liste, SqlValue pour une valeur.

    Plus de détails sur son utilisation ici :
    http://www.couscousboulette.com/2013...e-et-efficace/

  2. #2
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Je te le dis d'avance, je suis contre l'usage des singletons. J'en ai usé et abusé par le passé et je le regrette amèrement aujourd'hui. Plusieurs de mes projets on été tués par le singleton (sans rire). Donc ce que je vais dire va peut être te paraître brutal au premier abord. Je compte sur ton discernement pour faire la part des choses

    Considérons la fonction suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
     
    fonction pdo_connection () {
        static $pdo;
     
        if (func_num_args()) {
            list($dsn, $user, $pass, $options) = func_get_args + array('','','', array());
            $pdo = new PDO($dsn, $user, $pass, $options);
        }
     
        return $pdo;
    }
    Et cette autre fonction:
    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
    function pdo_query ($query, array $holders = array(), $fetch_mode = null) {
        static $pdo_types = array(
                'int'    => PDO::PARAM_INT,   'integer' => PDO::PARAM_INT,
                'double' => PDO::PARAM_STR,   'float'   => PDO::PARAM_STR,
                'bool'   => PDO::PARAM_BOOL,  'boolean' => PDO::PARAM_BOOL,
                'null'   => PDO::NULL,
            );
     
        if (!$pdo = pdo_connection())
            throw new RuntimeException("pdo_connection is not initialized");
     
        $stmt = $pdo->prepare($query);
     
        foreach ($holders as $key => $value) {
            $type = gettype($value);
            $stmt->bindValue(":$key", $value, isset($pdo_types[$type]) ? $pdo_types[$type] : PDO::PARAM_STR);
        }
     
        $fetch_mode && $stmt->setFetchMode($fetch_mode);
        return $stmt->execute() ? $stmt : false;
    }
    ça fait globalement la même chose, alors pourquoi as-t'on besoin d'une classe ? Pour des raisons pratiques liées à l'autoload ? Mauvaise idée, l'autoload n'est pas un moyen commode de faire de l'injection de dépendances et n'a jamais eu cette prétention. De plus, le singleton que tu propose n'a pas de réelle plus value métier à apporter, juste le cast lors de l'exécution de la requête, cast dont, en 5 ans de PHP avec PDO, je n'ai jamais eu besoin.

    Par ailleurs, les Singleton sont une très mauvaise approche de l'accès aux données et de l'architecture en général, ils favorisent le couplage entre les composants. Ils peuvent paraître pratiques au premier abord mais tout ceux qui s'en sont déjà servi au sein d'architectures un tant soit peu complexes le savent, ce n'est vraiment pas une bonne solution. Une fois le singleton solidement implanté dans l'infrastructure de l'application il devient difficile voire impossible de le déloger, c'est encore plus vrai au niveau de la couche modèle qu'il faut remplacer en intégralité si le besoin change.

    Quitte à utiliser quelque chose de statique et de transverse à l'application, pourquoi ne pas faire une façade pour un composant vraiment orienté objet qui peut évoluer et s'adapter à de nouveaux besoins ?

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/05/2012, 15h56
  2. [PDO] singleton pdo class ?
    Par altair8080 dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 23/04/2012, 12h14
  3. Copie efficace et rapide d'un fichier jpeg dans une autre destination
    Par Marginataman dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 03/09/2011, 11h37
  4. Réponses: 0
    Dernier message: 28/06/2011, 17h18
  5. LES TECHNIQUES DES SGBDR / MySQL rapide ???
    Par SQLpro dans le forum Langage SQL
    Réponses: 1
    Dernier message: 12/09/2003, 11h16

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