Pergunta

Qual é o benefício do uso de singleton em vez de global para conexões de banco de dados em PHP? Eu me sinto usando singleton em vez de marcas globais o código desnecessariamente complexos.

Code com a Global

$conn = new PDO(...);

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

Código com 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();
    .
    .
    .
}

Se há uma maneira melhor de inicializar conexão com o banco que não seja global ou singleton, por favor mencione isso e descrever as vantagens que ele tem singleton mais global ou.

Foi útil?

Solução

Eu sei que este é antiga, mas a resposta de Dr8k era quase lá.

Quando você está pensando em escrever um pedaço de código, suponha que vai mudar. Isso não significa que você está assumindo os tipos de mudanças que vai ter içadas sobre ele em algum momento no futuro, mas que de alguma forma de mudança será feita.

Faça-lhe um objetivo mitigar a dor de fazer mudanças no futuro: a global é perigoso porque é difícil de gerir em um único local. E se eu quiser fazer esse contexto de conexão de banco de dados conscientes no futuro? E se eu quero isso para fechar e reabrir-se a cada 5ª vez que foi usado. E se eu decidir que, no interesse de escalar meu aplicativo eu quero usar um pool de 10 conexões? Ou um número configurável de conexões?

A fábrica Singleton lhe dá essa flexibilidade. Eu configurá-lo com complexidade muito pouco extra e ganho mais do que o acesso apenas para a mesma conexão; Eu ganho a capacidade de mudança como essa conexão é passada para mim, mais tarde, de uma forma simples.

Note que eu digo fábrica Singleton ao invés de simplesmente Singleton . Há diferença muito pouco entre um singleton e uma global, verdadeiro. E por causa disso, não há nenhuma razão para ter uma conexão Singleton:? Por que você iria gastar o tempo definindo que quando você poderia criar um mundial regular em vez

O que uma fábrica faz com que você é um porquê para obter conexões, e um local separado para decidir quais as ligações (ou conexão), você vai conseguir.

Exemplo

class ConnectionFactory
{
    private static $factory;
    private $db;

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

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

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

Então, em 6 meses, quando a sua aplicação é super famoso e recebendo dugg e slashdotted e você decidir que precisa de mais do que uma única conexão, tudo que você tem a fazer é implementar algumas pooling na getConnection () método. Ou se você decidir que quer um wrapper que implementa SQL log, você pode passar uma subclasse PDO. Ou se você decidir que quer uma nova conexão em cada chamada, você pode fazer isso. É flexível, em vez de rígida.

16 linhas de código, incluindo chaves, que você vai economizar horas e horas e horas de refatoração para algo estranhamente similar para baixo da linha.

Note que eu não considero isso "Creep Recurso" porque eu não estou fazendo qualquer implementação recurso no primeiro go round. É da linha de fronteira "Future Creep", mas em algum momento, a ideia de que "a codificação para amanhã hoje" é sempre uma coisa ruim não jive para mim.

Outras dicas

Eu não estou certo de que posso responder à sua pergunta específica, mas queria sugerir que / global singleton objetos de conexão pode não ser a melhor idéia se isso se, por um sistema baseado em web. SGBDs são geralmente projetados para gerenciar um grande número de conexões únicas de uma maneira eficiente. Se você estiver usando um objeto de conexão global, então você está fazendo um par de coisas:

  1. forçando-o páginas para fazer tudo do banco de dados conexões sequencialmente e matança qualquer tentativa de página asyncronous cargas.

  2. Potencialmente mantendo os bloqueios abertos na elementos da base de dados mais longos do que necessário, abrandar geral banco de dados de desempenho.

  3. Atingir o máximo do número total de conexões simultâneas seus banco de dados pode apoiar e bloqueando novos usuários acessem a recursos.

Estou certo de que há outros potenciais consequências também. Lembre-se, este método irá tentar manter uma conexão de banco de dados para cada usuário que acessa o site. Se você tiver apenas um ou dois usuários, não um problema. Se este é um site público e você quiser o tráfego, em seguida, escalabilidade vai se tornar um problema.

[EDIT]

Em situações em escala maior, criando novas conexões Toda vez que você acertar o datase pode ser ruim. No entanto, a resposta é não criar uma conexão global e reutilizá-lo para tudo. A resposta é o pool de conexão.

Com pooling de ligação, um número de ligações distintas são mantidas. Quando uma conexão é exigida pelo aplicativo a primeira conexão disponível a partir da piscina é recuperado e depois voltou para a piscina uma vez seu trabalho está feito. Se uma conexão for solicitado e nenhum deles está disponível uma das duas coisas vai acontecer: a) se o número máximo de conexão permitida não for atingido, uma nova conexão é aberta, ou b) a aplicação é forçado a esperar por uma conexão para se tornar disponível .

Nota: idiomas no .net, pool de conexão é tratado pelo ADO.Net objetos por padrão (os conexão corda sets todas as informações necessárias).

Graças à Crad para comentar sobre este assunto.

O método singleton foi criado para garantir que não foi apenas uma instância de qualquer classe. Mas, porque as pessoas usá-lo como uma forma de atalho globalizante, torna-se conhecido como preguiçoso e / ou má programação.

Portanto, eu iria ignorar global e Singleton já que ambos não são realmente OOP.

O que você estava procurando injeção dependência .

Você pode verificar fácil de ler PHP informações com base relacionado com a injeção de dependência (com exemplos) em http://components.symfony-project.org/dependency-injection/trunk/book/01-Dependency-Injection

Ambos os padrões de conseguir o mesmo efeito líquido, fornecendo um ponto de acesso único para as chamadas de banco de dados.

Em termos de implementação específica, o singleton tem uma pequena vantagem de não iniciar uma conexão com o banco até que pelo menos um dos seus outros métodos solicite. Na prática, na maioria das aplicações que eu escrevi, isso não faz muita diferença, mas é uma vantagem potencial se você tem algumas páginas caminhos / execução que não fazem quaisquer chamadas de banco de dados em tudo, desde que essas páginas não vai sempre solicitar uma conexão com o banco de dados.

Uma outra diferença é menor que a implementação global pode pisar sobre outros nomes de variáveis ??na aplicação involuntariamente. É improvável que você nunca acidentalmente declarar outra referência global de US $ db, porém é possível que você poderia substituí-lo acidentalmente (por exemplo, você escreve if ($ db = null) quando você traz de escrever if ($ db == null). os singleton objeto impede isso.

Se você não está indo para usar uma conexão persistente, e há casos para não fazer isso, eu encontrar um singleton para ser conceitualmente mais palatável do que a global em design OO.

Em uma arquitetura OO verdade, um singleton é mais eficaz do que a criação de uma nova instância do objeto de cada vez.

No exemplo dado, não vejo nenhuma razão para usar singletons. Como regra geral, se a minha única preocupação é permitir que uma única instância de um objeto, se o idioma permite que ele, eu prefiro usar globals

Em geral, eu usaria um singleton para uma conexão de banco de dados ... Você não quer criar um novo toda conexão que você precisa para interagir com o banco de dados ... Esta perfomance ferido força e largura de banda da rede ... Por que criar um novo, quando há um disponível ... Apenas meus 2 centavos ...

RWendi

É muito simples. Nunca use global ou Singleton.

Como conselho tanto Singleton e Global são válidos e podem ser unidos no mesmo sistema, projeto, plugin, produto, etc .. . No meu caso, eu produzimos digital para web (plug-in).

I use somente Singleton na classe principal e eu usá-lo por princípio. Eu quase não usá-lo porque eu sei que a classe principal não irá instanciar-lo novamente

<?php // file0.php

final class Main_Class
{
    private static $instance;
    private $time;

    private final function __construct()
    {
        $this->time = 0;
    }
    public final static function getInstance() : self
    {
        if (self::$instance instanceof self) {
            return self::$instance;
        }

        return self::$instance = new self();
    }
    public final function __clone()
    {
        throw new LogicException("Cloning timer is prohibited");
    }
    public final function __sleep()
    {
        throw new LogicException("Serializing timer is prohibited");
    }
    public final function __wakeup()
    {
        throw new LogicException("UnSerializing timer is prohibited");
    }
}

Global uso para quase todas as classes secundárias, exemplo:

<?php // file1.php
global $YUZO;
$YUZO = new YUZO; // YUZO is name class

enquanto em tempo de execução eu posso usar Global para chamar seus métodos e atributos na mesma instância, porque eu não preciso de outra instância da minha classe principal produto.

<?php // file2.php
global $YUZO;
$YUZO->method1()->run();
$YUZO->method2( 'parameter' )->html()->print();

Eu fico com o global é usar a mesma instância para ser capaz de fazer o trabalho do produto, porque eu não preciso de uma fábrica para instâncias da mesma classe, geralmente a fábrica instância é para grandes sistemas ou para fins muito raros.

In conclusion:, você deve se você já entende muito bem que é o anti-padrão Singleton e compreender o Global , você pode usar uma das 2 opções ou misturá-los, mas se eu não recomendo a abuso uma vez que existem muitos programadores que são muito exceção e fiel à OOP programação, usá-lo para as classes principais e secundárias que você use um lote dentro do tempo de execução. (Isso evita que você um monte de CPU). ??

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top