static PDO - Connection MySQL

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : static PDO - Connection MySQL

Re: static PDO - Connection MySQL

par moogli » 22 janv. 2014, 17:38

Groumpf, j'ai pas trouvé de bouton "éditer"..!
si tu t'inscrit et dans un délais restreint tu peux le faire (le délais permet d'éviter la destruction, a posteriori, d'un message et qui ferais que l'on n'y comprendrait plus rien dans la lecture du post ;) )


@+

Re: static PDO - Connection MySQL

par Psyloh » 22 janv. 2014, 15:19

Groumpf, j'ai pas trouvé de bouton "éditer"..!

Je voulais préciser que l'exception dans le constructeur n'est pas destinée à être gérée par un try...catch mais plutôt à informer le programmeur qu'il a merdé en réinstanciant la classe Application, et donc qu'il y a un problème de conception dans son code! Donc, le but est d'interdire au programmeur de faire n'importe quoi avec des membres globaux qui sortent de nul part et de l'obliger à adopter des pratiques moins contraignantes en terme de debugging!

Ca, c'est l'effet recherché! Ma solution n'est pas forcément la bonne! Mes questions restent sans réponses, pour le moment! J'ai proposé cette solution en demandant si ça pourrait être une bonne idée dans le cadre de ce que je cherche à obtenir...

Re: static PDO - Connection MySQL

par Psyloh » 22 janv. 2014, 15:05

Mazarini, je vois que tu n'as pas vraiment lu le sujet!

La question ne porte pas sur le Singleton, mais sur les connexions aux BDD! Le Singleton étant ma première approche, Pitet m'a fournit de quoi comprendre que c'est le mal!
Je m'interroge principalement quant au fonctionnement interne d'Apache-PHP, de comment il gère les processus de traitement des requêtes et les files d'attente d'accès aux BDD...
Fin bon, il te suffit de scroller un coup pour consulter l'ensemble du sujet!

Et si je devais utiliser un Singleton, je préfèrerais un truc du genre :
trait Singleton {
    
    public static function getInstance() {
        static $instance = null;
        
        if (is_null($instance)) {
            
            $instance = new static();
        }
        
        return $instance;
    }
}

class Application {
    use Singleton;
    
    protected function __construct() {
        
    }
}
Le bout de code de mon message précédent à pour but d'assurer que l'Application est un Singleton tout en l'obligeant à être instancié explicitement par un new et ainsi éviter de déclarer un membre global!

Re: static PDO - Connection MySQL

par Mazarini » 22 janv. 2014, 13:28

Bonjour,

Je préfère un truc dans ce genre :
class Application {
    
    private static $application = NULL;
    
    private function __construct() {} // impossible à instancier de l'extérieur  

    public static function get_appilcation() {
        
        if (!self::$application instanceof self) {
            
            self::$application = new application();
        }
        
        return self::$application;
    }
}
On peut ainsi récupérer facilement une instance de l'objet et on ne risque pas de la déclarer 2 fois.

Re: static PDO - Connection MySQL

par Psyloh » 22 janv. 2014, 11:42

Coucou!

Merci pour ta réponse!
Très intéressant tout ça!

Je trouve ça dommage qu'il soit si difficile, voir impossible, de trouver des infos, par exemple via une simple recherche google, concernant le fonctionnement interne de PHP-Apache sans avoir à jouer les spéléologues dans la doc officielle...

Donc, si j'ai bien compris, Apache garde un ou plusieurs processus actifs, dédiés à mon site et, quand des clients se connectent :
- Apache dirige la requête vers le processus le moins chargé;
- Ce processus crée un processus enfant à moins d'en disposer d'un qui soit libre et pas encore détruit;

J'aimerais être sûr d'une chose : une connexion ne peut gérer qu'une transaction à la fois, n'est-ce pas?
Vu que mon site dispose d'un hébergement 1&1 minimal pour sites scriptés, à pas trop chère, j'imagine que peu de connexions concurrentes peuvent être ouvertes... Et donc, il faut que je sois sûr qu'une connexion persistante l'est avec mon site tout entier, et pas seulement avec un sous-processus de traitement... L'idéal serait que chaque new PDO obtienne bien l'instance du driver, même s'il est actuellement utilisé, puis qu'ensuite, Apache se débrouille..!

Ici, http://www.php.net/manual/fr/features.p ... ctions.php, les 2 paragraphes avant l'encadré d'avertissement me paraissent flous!
- Une connexion par processus enfant?
- Si le nombre de connexions est atteint, les processus enfants suivant restent sur le carreau?
- Ca veut dire qu'il faudrait que le nombre maximum de processus enfant soit inférieur ou égal au nombre maximum de connexions?
- Et, par rapport aux transactions, une transaction ouverte par une requête d'un client peut être fermée par une autre requête. Une requête de ce même client ou par n'importe quelle requête de n'importe quel client?

Quant au blog de Misko, si j'ai bien compris, il incite à hiérarchiser des Factory dans le but d'éviter les membres globaux..?
Seulement, en PHP, rien ne nous empêche de découper notre application en 150 includes! Et, à ce moment-là, il est impossible de savoir quand le PDO est instancié! Alors, une méthode du style Application::getPDO() peut paraitre intéressante...
D'un autre côté, si la classe Application se charge de toutes les instanciations, ce serait à elle de passer la connexion à qui en a besoin... J'ai pigé?
Bon, du coup, la classe Application ça l'empêche pas d'être un Singleton, si?
Parce qu'on pourrait très bien avoir besoin d'une instance d'Application dans un fichier qui n'est pas sensé savoir qu'elle a déjà été instanciée!
Ou s'il le faut vraiment, dans un soucis de clarté, est-ce que ceci pourrait être une bonne idée?
class Application {
    
    private static $existe = false;

    public function __construct() {
        
        if (self::$instance instanceof self) {
            
            throw new Exception('Classe Application déjà instanciée précédemment');
        }
        
        self::$exist = true;
    }
}
De cette façon, on est obligé d'instancier l'Application pour l'utiliser, et on s'assure qu'il n'existera pas 2 instances d'Application tout en prenant soin d'informer le programmeur qu'une erreur s'est glissée dans son modèle de conception et qu'il a malencontreusement chié dans la soupe en essayant d'instancier à nouveau la classe Application!

Je me demande aussi pourquoi Misko sépare l'instanciation de la classe Application et son initialisation? On pourrait l'initialiser dans le constructeur, non?

Encore merci pour cette grande baffe dans ma face! J'ai tendances à abuser des Singleton et des membres statiques et, c'est vrai que parfois, c'est terriblement chiant à débugguer! Ca va beaucoup m'aider à recentrer ma façon de coder vers des pratiques moins "evil"!

Re: static PDO - Connection MySQL

par Pitet » 20 janv. 2014, 15:34

Salut,

En reprenant tes questions dans l'ordre :
- Oui l'instance PDO est détruite à la fin du script, comme tout ce qui est en mémoire (PHP est un langage "stateless"). Le mot clé static indique uniquement que la méthode peut être appelée sans avoir besoin de créer une instance de la classe DB.
- Non, une connexion persistante n'est pas fermée à la fin du script, c'est l’intérêt d'une connexion persistante. Plus de détail ici : http://www.php.net/manual/fr/features.p ... ctions.php
- Oui, pour ouvrir une connexion persistante avec PDO, tu dois définir un paramètres lors de l'instanciation de l'objet PDO, un exemple ici : http://php.net/manual/fr/pdo.connection ... xample-919 Mais non, chaque client n'ouvre pas sa connexion persistante (cf. lien sur les connexions persistantes du point précédent).
- La bonne manière d'ouvrir une connexion persistante "partagée pour tous" correspond à l'exemple du point précédent.

Enfin non, le singleton ne permet de créer une connexion persistante (c'est le rôle du paramètre PDO::ATTR_PERSISTENT). Le singleton permet uniquement de créer une seule fois ta connexion à la base de données dans le script. A chaque appel de ton script, le singleton sera recréé.

Si le fait de gérer la connexion à la bdd était souvent couplée avec le design pattern singleton, il semble finalement que ceci soit une mauvaise pratique pour plusieurs bonnes raisons. D'après certains, le pattern singleton en lui même ne devrait pas être utilisé.
Plus d'éléments de réponse ici :
- Global or Singleton for database connection? http://stackoverflow.com/questions/1308 ... connection
- What is so bad about Singletons? http://stackoverflow.com/questions/1379 ... singletons

Bonne journée

static PDO - Connection MySQL

par Psyloh » 20 janv. 2014, 14:40

Salut à tous!

Jadis, lors de ma formation, on nous a fait implémenter un PDO en singleton, du style :
class DB {
static $pdo = null;

public static function getInstance() {
if (!(self::$instance instanceof PDO)) self::$instance = new PDO();
return self::$instance;
}
}
On nous a dit que ça permettait d'avoir une connexion persistante!
J'ai quelques questions vis à vis de cela...

- L'instance de PDO est bien détruite à la fin du script, malgré le static? Il parait logique que oui, mais avec ce qu'on nous a dit, je garde un doute ^^
- Si l'instance est détruite à la fin du script, alors la connexion est persistante pour le script en cours et il reviendrait au même d'ouvrir le PDO au début du script, non?
- Pour avoir une connexion persistante, j'ai vu qu'on pouvait préciser un attribut au driver au moment de son instanciation! Mais, à ce moment, chaque client qui se connecte ouvre sa propre connexion persistante, non?
- Y a-t-il un moyen d'ouvrir une connexion persistante partagée par tous? Sérialisation dans un fichier? Et est-ce que ça parait être une bonne idée?

Merci à vous!
Bonne aprèm'!