140 votes

Y a-t-il un cas d’utilisation pour les singletons avec accès base de données en PHP ?

- Je accéder à ma base de données MySQL via PDO. Je suis à la configuration de l'accès à la base de données, et ma première tentative a été d'utiliser les éléments suivants:

La première chose que j'ai pensé de est - global:

$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'root', 'pwd');

function some_function() {
    global $db;
    $db->query('...');
}

Ceci est considéré comme une mauvaise pratique. Après un peu de recherche, j'ai fini avec le pattern Singleton, qui

"s'applique à des situations dans lesquelles il doit y avoir une seule instance d'une classe."

Selon l'exemple dans le manuel, nous devrions faire ceci:

class Database {
    private static $instance, $db;

    private function __construct(){}

    static function singleton() {
        if(!isset(self::$instance))
            self::$instance = new __CLASS__;

        return self:$instance;
    }

    function get() {
        if(!isset(self::$db))
            self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd')

        return self::$db;
    }
}

function some_function() {
    $db = Database::singleton();
    $db->get()->query('...');
}

some_function();

Pourquoi ai-je besoin de relativement grande classe quand je peux le faire?

class Database {
    private static $db;

    private function __construct(){}

    static function get() {
        if(!isset(self::$rand))
            self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd');

        return self::$db;
    }
}

function some_function() {
    Database::get()->query('...');
}

some_function();

Ce dernier fonctionne parfaitement et je n'ai pas besoin de vous soucier $db plus.

Comment puis-je créer une petite classe singleton, ou est-il un cas d'utilisation pour les singletons que je suis absent en PHP?

323voto

Gordon Points 156415

Les Singletons ont très peu - pour ne pas dire aucun - utilisation en PHP.

Dans les langues où les objets vivants dans la mémoire partagée, les Singletons peuvent être utilisés pour garder l'utilisation de la mémoire faible. Au lieu de créer deux objets, vous faites référence à une instance existante de l'communes à l'échelle mondiale la mémoire de l'application. En PHP il n'y a aucune application de ce type de mémoire. Un Singleton créé dans une Requête vie pour exactement à cette demande. Un Singleton créé dans une Demande faite en même temps c'est encore un de complètement différent de l'instance. Ainsi, l'un des deux principaux objectifs d'un Singleton n'est pas applicable ici.

En outre, de nombreux objets qui peuvent théoriquement exister qu'une seule fois dans votre application n'avez pas nécessairement besoin d'une langue mécanisme pour faire appliquer le présent. Si vous avez besoin d' une seule instance, puis de ne pas instancier un autre. C'est seulement lorsqu'on ne peut avoir aucune autre instance, par exemple lorsque les chatons meurent lorsque vous créez un second exemple, que vous pourriez avoir un valide en Cas d'Utilisation d'un Singleton.

L'autre objectif serait d'avoir un mondial de point d'accès à une instance dans la même Demande. Même si cela peut paraître souhaitable, il n'est pas vraiment, car il crée de l'accouplement à la portée globale (comme toutes les variables globales et statiques). Cela rend l'Unité de Test plus difficile et à votre demande en général moins maintenable. Il y a des moyens pour atténuer ce problème, mais en général, si vous avez besoin d'avoir la même instance dans beaucoup de classes, d'utiliser l'Injection de Dépendance.

Voir mes photos pour les Singletons en PHP - Pourquoi ils sont mauvais et comment vous pouvez les éliminer de vos applications pour plus d'informations.

Même Erich Gamma, l'un des pattern Singleton inventeurs, les doutes, ce modèle aujourd'hui:

"Je suis en faveur de l'abandon de Singleton. Son utilisation est presque toujours une conception de l'odeur"

Lectures complémentaires

Si, après ce qui précède, vous avez encore besoin d'aide pour faire votre choix:

Singleton Decision Diagram

82voto

Bill K Points 32115

Ok, je me demandais de plus que l'un pendant un certain temps, lorsque j'ai commencé ma carrière. Mis en œuvre de différentes façons et est venu avec deux de raisons de choisir de ne pas utiliser les classes statiques, mais ils sont assez gros.

La première est que vous verrez que très souvent quelque chose que vous êtes absolument sûr que vous n'aurez jamais plus d'une instance d', on finit par avoir un deuxième. Vous pouvez vous retrouver avec un deuxième moniteur, une seconde base de données, un second serveur--que ce soit.

Lorsque cela se produit, si vous avez utilisé une classe statique, vous êtes dans un bien pire refactoriser que si vous aviez utilisé un singleton. Un singleton est un terrible motif en lui-même, mais il convertit assez facilement à un système intelligent d'usine modèle--peut-être même converti à utiliser l'injection de dépendance sans trop de difficultés. Par exemple, si votre singleton est obtenu à travers getInstance(), vous pouvez très facilement changer cela pour getInstance(databaseName) et permettent de multiples bases de données--pas d'autres changements dans le code.

La deuxième question est de tester (Et honnêtement, c'est la même que la première question). Parfois, vous voulez remplacer votre base de données avec une maquette de la base de données. En effet c'est une deuxième instance de l'objet de base de données. C'est beaucoup plus difficile à faire avec les classes statiques que c'est avec un singleton, vous n'avez qu'à se moquer de la méthode getInstance (), pas chaque méthode dans une classe statique (qui, dans certaines langues, il peut être très difficile).

Il s'agit vraiment d'habitudes-et quand les gens disent "Globals" sont mauvais, ils ont de très bonnes raisons de le dire, mais il ne peut pas toujours être évident jusqu'à ce que vous avez touché le problème vous-même.

La meilleure chose que vous pouvez faire est de demander (comme vous l'avez fait) puis faire un choix et d'observer les conséquences de votre décision. Avoir les connaissances nécessaires pour interpréter votre code de l'évolution au cours du temps est beaucoup plus important que de le faire à droite dans la première place.

15voto

Will Vousden Points 13332

Les Singletons sont considérés par beaucoup comme des anti-modèles comme ils sont vraiment glorifié variables globales. Dans la pratique, il y a relativement peu de scénarios dans lesquels il est nécessaire pour une classe d'avoir une seule instance; habituellement, c'est juste qu'une instance est suffisant, dans ce cas la mise en œuvre comme un singleton est complètement inutile.

Pour répondre à la question, vous avez raison, les singletons sont des exagéré ici. Une simple variable ou de la fonction le fera. Une meilleure (plus robuste) approche, cependant, serait d'utiliser l'injection de dépendance pour supprimer la nécessité pour les variables globales au total.

8voto

Paul Sasik Points 37766

Dans votre exemple, vous avez affaire avec une seule pièce de apparemment immuable de l'information. Pour cet exemple un Singleton serait exagéré, et seulement à l'aide d'une fonction statique dans une classe fera l'amende juste.

Plus de pensées: Vous pourriez être confronté à un cas de mise en œuvre de modèles pour l'amour de modèles et de votre instinct vous dit "non, vous n'avez pas à" pour les raisons que vous avez défini.

MAIS: Nous n'avons aucune idée de la taille et de la portée de votre projet. Si c'est un code simple, peut-être à jeter, qui n'est pas susceptible d'avoir besoin de changer alors oui, allez-y et utilisez des membres statiques. Mais, si vous pensez que votre projet pourrait avoir besoin d'évoluer ou d'être préparée pour l'entretien de codage en bas de la route alors, oui, vous pouvez utiliser le pattern Singleton.

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