Global o Singleton para la conexión de base de datos?

¿Cuál es el beneficio de la utilización de singleton en lugar de global de conexiones de base de datos en PHP? Me siento uso de singleton en lugar de global hace que el código innecesariamente complejo.

Código Mundial

$conn = new PDO(...);

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

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

Si hay una mejor manera de inicializar la base de datos de conexión que no sea global o singleton, por favor mencione y describa las ventajas que tienen más global o singleton.

InformationsquelleAutor Imran | 2008-09-25

9 Kommentare

  1. 104

    Sé que esto es viejo, pero Dr8k, fue la respuesta de casi allí.

    Cuando usted está pensando en escribir un fragmento de código, asuma que va a cambiar. Eso no significa que usted está asumiendo que los tipos de cambios que se han izado sobre él en algún momento en el futuro, sino que de alguna forma el cambio será hecho.

    Hacer de ella un objetivo de mitigar el dolor de hacer cambios en el futuro: un mundial es peligroso porque es difícil de gestionar en un solo punto. Lo que si quiero hacer que la conexión de base de datos en cuenta el contexto en el futuro? Lo que si quiero es cerrar y volver a abrir cada 5ª vez que se utilizó. ¿Y si decido que en el interés de la ampliación de mi aplicación que desee utilizar una piscina de 10 conexiones? O una cantidad configurable de conexiones?

    Un singleton fábrica te da la flexibilidad. Yo lo arme con muy poco más de complejidad y ganan más que el acceso a la misma conexión; me gana la habilidad de cambiar la forma en que la conexión se pasa a mí más adelante en una manera simple.

    Nota que digo singleton fábrica en contraposición a simplemente singleton. Hay muy poca diferencia entre un singleton y global, por cierto. Y a causa de eso, no hay ninguna razón para tener un singleton de conexión: ¿por qué gastar el tiempo de configuración que cuando usted podría crear un regular global en su lugar?

    Lo que una fábrica consigue es un por qué para obtener conexiones, y un punto separado para decidir qué conexiones (o conexión) vas a conseguir.

    Ejemplo

    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();
        .
        .
        .
    }

    Luego, en 6 meses, cuando su aplicación es super famoso y conseguir dugg y slashdotted y decide que necesita más de una conexión, todo lo que tienes que hacer es implementar la puesta en común en la getConnection() método. O si usted decide que quiere un contenedor que implementa el registro de SQL, puede pasar un PDO de la subclase. O si usted decide que quiere una nueva conexión en cada invocación, usted puede hacer eso. Es flexible, en lugar de rígido.

    16 líneas de código, incluyendo los apoyos, lo que le ahorrará horas y horas y horas de refactorización para algo inquietantemente similar hacia abajo de la línea.

    Nota que no tienen en cuenta esta Característica de «Creep» porque yo no estoy haciendo ningún implementación de la función en la primera ronda. Es la línea de frontera del Futuro «Creep», pero en algún momento, la idea de que «la codificación para el mañana, hoy» es siempre una mala cosa no jive para mí.

    • No estoy seguro, pero creo que usted quiso decir: de la función pública getConnection() { if (!$esto->db) $this->db = new PDO(…); return $this->db; }
    • Gracias! Iba yo a perder ninguna de las ventajas de utilizar este método con return self::$factory->getConnection(); en lugar de return self::$factory; ?
    • Me gustaría utilizar este código en un proyecto que estoy haciendo. Puedo citar esta página, y si es así, qué tipo de licencia es este texto? Es CC-BY, BSD o algo más? He actualmente afirmó que esta como «Desconocido – creo Dominio Público», pero me gustaría atributo de la licencia correcta de las condiciones en él.
    • Creo que deberíamos hacer «$db» «$this->db» en la getConnection() método, de lo contrario, «private $db» variable «no se usa», que no es oficial que se hace referencia en cualquier lugar.
    • Hola su solución se ve fresco y escalable. Por favor, hágamelo saber lo que se necesita para ser implementado aquí self::$fábrica = new ConnectionFactory(…);
    • Gracias por este excelente información. He estado lidiando con este problema,yo hice la instalación de mi marco del db conexiones con un objeto singleton, y cuando tenía que hacer algunas operaciones con procesos paralelos, me equivocaba. Con su forma de pensar, he hecho mis pruebas con éxito. Sólo tiene que actualizar mi código que tengo miedo de antes, pero ahora no creo que me lo voy a hacer cambiar mucho después de todo. Un gran agradecimiento a D. Raphaelson.

  2. 16

    No estoy seguro de que puedo responder a tu pregunta específica, pero quería sugerir que global /singleton objetos de conexión puede no ser la mejor idea si esto si, por un sistema basado en la web. Dbms son generalmente diseñados para gestionar un gran número de conexiones únicas de una manera eficiente. Si usted está usando un objeto de conexión global, entonces usted está haciendo un par de cosas:

    1. Obligando a las páginas para hacer todo de la base de datos
      conexiones de forma secuencial y matar
      cualquier intento en asincrónica página
      las cargas.

    2. Potencialmente la celebración de abrir las cerraduras en
      elementos de base de datos de más de
      necesario, la desaceleración global
      rendimiento de base de datos.

    3. Maximizar el número total de
      conexiones simultáneas su
      base de datos puede apoyar y bloqueo
      los nuevos usuarios el acceso a la
      recursos.

    Estoy seguro de que hay otras posibles consecuencias. Recuerde, este método intento de mantener una conexión de base de datos para cada usuario que accede al sitio. Si sólo tiene uno o dos usuarios, no es un problema. Si este es un sitio web público y desea tráfico, a continuación, la escalabilidad se convertirá en un problema.

    [EDITAR]

    En mayor escala de las situaciones, la creación de nuevas conexiones cada vez que golpeas la datase puede ser malo. Sin embargo, la respuesta no es para crear una conexión global y usarlo para todo. La respuesta es la agrupación de conexiones.

    Con la agrupación de conexiones, un número de diferentes conexiones se mantienen. Cuando una conexión es requerido por la aplicación de la primera conexión de la piscina se recupera y luego regresó a la piscina una vez que su trabajo está hecho. Si se solicita una conexión, y ninguno está disponible una de dos cosas va a suceder: a) si el número máximo permitido de conexión no es llegar, una nueva conexión se abre, o b) la aplicación se ve obligado a esperar una conexión esté disponible.

    Nota: En .Net languages, la agrupación de conexiones es manejado por el ADO.Net los objetos por defecto (la cadena de conexión, conjuntos de toda la información requerida).

    Gracias a Crad para comentar sobre esto.

    • Supongo que el uso de singleton me da la ventaja de inicialización de la conexión tan tarde como sea posible, mientras que si uso global, probablemente me inicializar casi al principio de la secuencia de comandos. Estoy en lo cierto?
    • Correcto, si se va a ir por este camino el singleton podría proporcionar ventaja.
    • En realidad, todo depende de la escala. En la web de gran escala de las implementaciones grandes cantidades de DB conexiones están mal. Esta es la razón por aplicaciones como pgBouncer existen para PostgreSQL y Java hace la agrupación de recursos.
    • Cierto, pero creo que la correcta conexión de la agrupación es diferente a simplemente mediante mundial de la conenction objetos. La agrupación de conexiones todavía utiliza varias conexiones, simplemente se limita el número máximo y resuses ellos a lo largo del tiempo para allieviate de configuración generales.
    • Tenga en cuenta que «global» en el caso de PHP no es hacer que la variable global a través de páginas PHP. Sólo significa que se puede acceder desde dentro de funciones.
  3. 7

    El singleton método fue creado para asegurarse de que no era sólo una instancia de cualquier clase. Pero, porque la gente lo usa como una forma de acceso directo de globalización, que se la conoce como perezoso y/o la mala programación.

    Por lo tanto, me gustaría ignorar global y Singleton ya que ambos no son realmente programación orientada a objetos.

    Lo que se busca es la inyección de dependencia.

    Puede comprobar fácil de leer PHP basado en la información relativa a la inyección de dependencia (con ejemplos) en http://components.symfony-project.org/dependency-injection/trunk/book/01-Dependency-Injection

  4. 3

    Tanto los patrones de lograr el mismo efecto de la red, proporcionando un único punto de acceso para la base de datos de llamadas.

    En términos de implementación específica, el singleton tiene una pequeña ventaja de no iniciar una conexión de base de datos hasta que al menos uno de los otros métodos solicita. En la práctica, en la mayoría de las aplicaciones que he escrito, esto no tiene mucho de una diferencia, pero es una ventaja potencial si usted tiene algunas páginas/rutas de ejecución que no haga ningún tipo de base de datos de llamadas a todas, ya que esas páginas no siempre solicita una conexión a la base de datos.

    Otra pequeña diferencia es que la aplicación global puede pisotear a otros nombres de variable en la aplicación de forma involuntaria. Es poco probable que alguna vez accidentalmente declarar otro global $db de referencia, aunque es posible que usted podría sobrescribir accidentalmente ( por ejemplo, escribir if($db = null) cuando se pretende escribir if($db) = = null). El objeto singleton impide que.

    • Pero, de nuevo, claramente probar el código antes de implementarlo, así que…
  5. 2

    Si no vas a utilizar una conexión persistente, y hay casos para no hacerlo, me parece un singleton para ser conceptualmente más apetecible que el de un mundial en el diseño OO.

    En un verdadero OO arquitectura, un singleton es más eficaz que la creación de una nueva instancia del objeto cada vez.

    • Un singleton ES un mundial!
  6. 2

    En el ejemplo dado, no veo razón para el uso de los embarazos únicos. Como regla general, si mi única preocupación es la de permitir que una sola instancia de un objeto, si el lenguaje lo permite, yo prefiero usar variables globales de

  7. 1

    En general, me gustaría utilizar un singleton para una conexión de base de datos… Usted no desea crear una nueva conexión cada vez que usted necesita para interactuar con la base de datos… Esto puede doler el rendimiento y el ancho de banda de tu red… ¿por Qué crear uno nuevo, cuando hay uno disponible… Solo mis 2 centavos…

    RWendi

    • Con la inicialización de la conexión en el ámbito global, estoy inicialización de la conexión de una vez por página, y usando esa variable global en las funciones que necesita para interactuar con la base de datos.
    • El uso de un singleton para una conexión de base de datos no es el mismo de no volver a crear la conexión en cada interacción con el DBMS. Un singleton es sólo eso; una instancia de una clase determinada, y el único que permitió a los existentes en el mundo. Usted puede ser que necesite conectarse a diferentes bases de datos a la vez.
    • me estaba refiriendo a una clase singleton que administra las conexiones a la base de datos. Yo no veo el punto de crear un nuevo objeto de conexión cada vez que usted desea interactuar a un dbms. Por supuesto, si usted necesita para conectarse a la base de datos diferente a la vez, puede que necesite crear otro objeto de conexión.
  8. 0

    Es bastante simple. Nunca uso global O Singleton.

    • Cuando se trata del patrón Singleton, siempre digo que nunca
    • Yo odio el Singleton tanto como el tipo de al lado, pero tiene sus usos. ¿Qué acerca del registro?
    • Lo que si desea más de un proveedor de registro? ¿Quién dice que no puedo acceder a un archivo, y la consola?
    • ¿Qué pasa si usted quiere tener nombre de las clases? Aún sin datos estáticos, que todavía están en la const globales.
    • También son los únicos, si usted tiene meta-clases.
    • Los únicos que puede tener el estado; puede llamar a incubadoras para cambiar la salida de un Registrador, por ejemplo. Ellos proporcionan una forma conveniente para acceder a los objetos sin pasar punteros de todo el lugar. A veces esto aumenta la comodidad de acoplamiento, a veces hace que las cosas más simples. Depende del contexto.
    • De lado el nombre de las clases, el uso principal que he encontrado para Singleton es la representación de algo que existe objetivamente es sólo uno en relación a mi programa o cualquier tipo de programa usando mi clase de la API. «El Sistema Operativo», por ejemplo. Todavía es arriesgado en el sentido de que usted puede ser que desee para Burlarse de ella.
    • Así que, a continuación, combinar un anti-patrón (Singleton) con otro (Dios de Objeto)
    • Sí. Y también lo hacen los diseñadores de cada una de las principales lenguaje de programación orientada a objetos, permitiendo global de los objetos de la clase. Si eres un monoteísta y desea que un objeto para representar a Dios, entonces lo que estás buscando es un Singleton Dios Objeto. Otra cosa es incorrecta.
    • Yo también tenga en cuenta que usted ha ofrecido ninguna explicación, como pero, ¿por qué ninguno de estos patrones están contraindicados. Podríamos tener un argumento donde puedo preguntar retóricamente si usted va a utilizar el anti-modelo «entero». Tendría que ser educativo?
    • Si yo era un montheist y quería crear un Dios objeto, yo podría especificar el uso de un MonotheistAbstractFactory Patrón para crear mi Dios Objeto? Esto dejaría abierta la posibilidad de politeístas, los usuarios también utilizar mi programa mediante la especificación de un PolytheistAbstractfactory.
    • Por qué no está contraindicado, si usted está de acuerdo que un Singleton es el mismo como una variable global, entonces debemos convenir con cada uno de los otros que globals son malos y deben ser evitados.
    • También Singleton es esencialmente de la onu-comprobables y se esconde estado global.
    • Debe ser evitado. No debe ser evitado. Es útil para el código de la aplicación para ser capaces de asumir que hay un solo Dios, y para el prueba código a tener que ir alrededor de las casas, en algunos idiomas, dependiente de la manera en que para hacer su trabajo. Sí, Singleton es una variable global. Así se denominan las clases. Para qué las utilizan?
    • Propuesta de compromiso: un Dios único (como sólo hay un PID 0), pero el 99% de código debe encontrar un Sacerdote (o crear instancias de su propia Oración si protestante) y de interactuar a través de eso. Eso es fácilmente comprobable. De todos modos, Dios, el eterno, es inmutable: reducir enormemente los peligros de las globales.
    • En realidad no creo en comadreja recomendaciones. Nunca decir «debe» cuando puedes decir «debe».
    • Estoy de acuerdo, no hay ninguna razón para el uso de variables globales o los únicos que crean en DIOS como objetos y no realmente de la programación orientada a objetos. La inyección de dependencia es el camino a seguir aquí! Recuerden, es PHP… no la NETA! 😉

  9. 0

    Como asesoramiento tanto singleton y global son válidos y pueden unirse dentro de la misma sistema, proyecto, plugin, producto, etc
    En mi caso, yo hago de productos digitales para web (plugin).

    Yo sólo uso singleton en la clase principal, y lo uso por el principio. Yo casi no lo uso porque sé que la clase principal no crear instancias de ella de nuevo

    <?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 casi todas las clases secundarias, por ejemplo:

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

    mientras que en tiempo de ejecución puedo usar Global llamar a sus métodos y atributos en la misma instancia porque no necesito otra instancia de mi producto principal de la clase.

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

    Que tengo con el mundial es el uso de la misma instancia a ser capaz de hacer que el producto del trabajo porque no necesito una fábrica de instancias de la misma clase, generalmente de la instancia de la fábrica es para los sistemas grandes o muy raros efectos.

    In conclusion:, usted debe si ya entiendo bien que es el anti-patrón Singleton y entender el Global, puede usar una de las 2 opciones o la combinación de ellos, pero si me recomiendan no abusar, ya que hay muchos programadores que están muy de excepción y a los fieles a la programación programación orientada a objetos, se usa para el principal y secundaria de las clases que se usan mucho en el tiempo de ejecución. (Se ahorra un montón de CPU). 😉

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea