79 votes

Global ou Singleton pour la connexion à la base de données?

Quel est l'avantage d'utiliser singleton au lieu de global pour les connexions de base de données en PHP? Je pense que l'utilisation de singleton au lieu de global rend le code inutilement complexe.

Code avec Global

 $conn = new PDO(...);

function getSomething()
{
    global $conn;
    .
    .
    .
}
 

Code avec Singleton

 class DB_Instance
{
    private static $db;

    public static function getDBO()
    {
    	if (!self::$db)
    		self::$db = new PDO(...);

    	return self::$db;
    }
}

function getSomething()
{
    $conn = DB_Instance::getDBO();
    .
    .
    .
}
 

S'il existe un meilleur moyen d'initialiser une connexion à une base de données autre que globale ou singleton, veuillez la mentionner et décrire les avantages qu'elle présente par rapport à global ou singleton.

104voto

Jon Raphaelson Points 874

Je sais que c'est vieux, mais Dr8k réponse était presque là.

Lorsque vous envisagez d'écrire un bout de code, à supposer qu'il va changer. Cela ne signifie pas que vous êtes en supposant que les types de changements ont été hissées sur elle à un certain moment dans l'avenir, mais plutôt d'une certaine forme de changement ne sera effectué.

En faire un objectif d'atténuer la douleur de faire des changements dans l'avenir: un mondial est dangereux parce qu'il est difficile de gérer en un seul endroit. Que faire si je veux faire pour que la connexion de base de données, tenant compte du contexte dans l'avenir? Que faire si je veux la fermer et rouvrir lui-même à chaque fois 5, il a été utilisé. Que faire si je décide que, dans l'intérêt de la mise à l'échelle de mon appli je veux utiliser un pool de 10 connexions? Ou un nombre configurable de connexions?

Un singleton, factory vous donne de la flexibilité. Je l'ai installé avec très peu plus de complexité et de gagner plus qu'un simple accès à la même connexion; - je avoir la capacité de changer la façon dont la connexion n'est passé pour moi, plus tard, d'une manière simple.

Notez que je dis singleton usine plutôt que de simplement singleton. Il n'y a guère de différence entre un singleton et mondial, vrai. Et à cause de cela, il n'y a aucune raison d'avoir un singleton connexion: pourquoi voudriez-vous passer du temps à mettre en place lorsque vous pouvez créer un régulier global à la place?

Ce qu'est une usine, vous reçoit est pourquoi pour obtenir des connexions, et un endroit distinct de décider ce que les connexions (ou connexion) vous allez obtenir.

Exemple

class ConnectionFactory
{
    private static $factory;
    public static function getFactory()
    {
        if (!self::$factory)
            self::$factory = new ConnectionFactory(...);
        return self::$factory;
    }

    private $db;

    public function getConnection() {
        if (!$db)
            $db = new PDO(...);
        return $db;
    }
}

function getSomething()
{
    $conn = ConnectionFactory::getFactory()->getConnection();
    .
    .
    .
}

Puis, dans 6 mois lorsque votre application est super célèbre et se dugg et slashdotted et vous décidez que vous avez besoin de plus qu'un unique de connexion, tout ce que vous avez à faire est de mettre en œuvre certaines de regroupement dans la méthode getConnection (). Ou si vous décidez que vous voulez un wrapper qui implémente la journalisation SQL, vous pouvez passer une sous-classe PDO. Ou si vous décidez que vous voulez une nouvelle connexion à chaque invocation, vous pouvez le faire faire. Il est flexible, au lieu de rigide.

16 lignes de code, y compris des accolades, qui vous permettra d'économiser des heures et des heures et des heures de refactoring pour quelque chose d'étrangement similaire en bas de la ligne.

Note que je ne considère pas cette "Feature Creep" parce que je ne suis pas de faire toute la fonctionnalité de mise en œuvre lors du premier tour. C'est border line "Avenir de Fluage", mais à un certain point, l'idée que "codant pour demain" est toujours une mauvaise chose de ne pas jive pour moi.

16voto

Dr8k Points 902

Je ne suis pas sûr que je peux répondre à votre question, mais je voulais suggérer que global / singleton objets de connexion peut ne pas être la meilleure idée si ce si pour un système basé sur le web. Les sgbd sont généralement conçus pour gérer un grand nombre de unique connexions de manière efficace. Si vous utilisez une connexion globale de l'objet, alors que vous faites un certain nombre de choses:

  1. Vous forçant pages à faire de la base de données les connexions de façon séquentielle et de tuer toutes les tentatives d'un système de page les charges.

  2. Potentiellement holding ouvrir les serrures sur éléments de base de données de plus de nécessaire, le ralentissement global de l' les performances de la base.

  3. Maxing sur le nombre total de connexions simultanées votre la base de données peut prendre en charge et de blocage les nouveaux utilisateurs d'accéder à l' les ressources.

Je suis sûr qu'il y a d'autres conséquences potentielles. Rappelez-vous, cette méthode va tenter de maintenir une connexion de base de données pour chaque utilisateur qui accède au site. Si vous avez seulement un ou deux utilisateurs, pas de problème. Si c'est un site web et que vous voulez du trafic, de l'évolutivité deviendra un problème.

[MODIFIER]

À plus grande échelle les situations, en créant de nouvelles connexions chaque fois que vous frappez la datase peut être mauvais. Cependant, la réponse n'est pas de créer une connexion globale et de la réutiliser pour tout. La réponse est le regroupement de connexion.

Avec le regroupement de connexions, un certain nombre de connexions différentes sont maintenus. Lorsqu'une connexion est nécessaire à l'application de la première connexion disponible à partir de la piscine est récupéré et est ensuite retourné à la piscine une fois son travail terminé. Si une connexion est requise et aucun n'est disponible de l'une des deux choses vont se produire: a) si le nombre maximum de connexion n'est pas atteint, une nouvelle connexion est ouverte, ou b) la demande est obligé d'attendre pour une connexion à devenir disponibles.

Remarque: Dans .Net languages, de raccordement, de mise en commun est géré par le ADO.Net des objets par défaut (la chaîne de connexion définit toutes les informations requises).

Grâce à Crad'pour commenter sur cette.

3voto

Adam N Points 3395

Les deux modèles d'atteindre le même effet net, en fournissant un point d'accès unique pour vos appels de base de données.

En termes de mise en œuvre spécifiques, le singleton a un petit avantage de ne pas initier une connexion de base de données jusqu'à ce qu'au moins un de vos méthodes les demandes. Dans la pratique, dans la plupart des applications que j'ai écrit, ce n'est pas beaucoup de différence, mais c'est un avantage potentiel si vous avez des pages/chemins d'exécution qui ne fais pas d'appels de base de données à tous, depuis que ces pages ne jamais demander une connexion à la base de données.

Une autre petite différence est que la mise en œuvre globale peut empiéter sur les autres noms de variable dans l'application involontairement. Il est peu probable que vous aurez jamais accidentellement déclarer une autre global $db de référence, mais il est possible que vous pourriez écraser accidentellement ( par exemple, vous écrivez si($db = null) quand vous pensez à écrire if($db == null). L'objet singleton en empêche.

2voto

Gavin M. Roy Points 1501

Si vous n'utilisez pas une connexion persistante, et qu'il existe des cas de ne pas le faire, je trouve un singleton conceptuellement plus acceptable qu'un design global en mode OO.

Dans une véritable architecture OO, un singleton est plus efficace que la création d'une nouvelle instance de l'objet à chaque fois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X