Patrón Singleton Práctica.


En ciertas ocasiones se necesita que una clase en concreto mantenga la misma y única instancia a lo largo de toda la ejecución del programa, sin permitir que se cree un objeto diferente de esa clase.
Se implementa:
·         Se declara una propiedad de la clase con visibilidad privada que va a contener en todo momento la instancia de la clase.
·         Se establece como privado el constructor de la clase.
·         Se crea un método de acceso público getInstance que se encargará de devolver la instancia de la clase si existe, y si no existe la crea previamente.

Este patrón obliga a instanciar únicamente una vez la clase para evitar 2 o más conexiones simultáneas. La clase contiene métodos para ejecutar sentencias SQL, cargar resultados en forma de objetos, ver el número de consultas totales etc.

<?php

class DataBase {

      private $conexion;
      private $resource;
      private $sql;
      public static $queries;
      private static $_singleton;
     
      public static function getInstance(){
            if (is_null (self::$_singleton)) {
                  self::$_singleton = new DataBase();
            }
            return self::$_singleton;
      }
     
      private function __construct(){
            $this->conexion = @mysql_connect('localhost', 'root', '');
            mysql_select_db('bdbeauty', $this->conexion);
            $this->queries = 0;
            $this->resource = null;
      }
     
      public function execute(){
            if(!($this->resource = mysql_query($this->sql, $this->conexion))){
                  return null;
            }
            $this->queries++;
            return $this->resource;
      }
     
      public function alter(){
            if(!($this->resource = mysql_query($this->sql, $this->conexion))){
                  return false;
            }
            return true;
      }
     
      public function loadObjectList(){
            if (!($cur = $this->execute())){
                  return null;
            }
            $array = array();
            while ($row = @mysql_fetch_object($cur)){
                  $array[] = $row;
            }
            return $array;
      }
     
      public function setQuery($sql){
            if(empty($sql)){
                  return false;
            }
            $this->sql = $sql;
            return true;
      }
     
      public function freeResults(){
            @mysql_free_result($this->resource);
            return true;
      }
     
      public function loadObject(){
            if ($cur = $this->execute()){
                  if ($object = mysql_fetch_object($cur)){
                        @mysql_free_result($cur);
                        return $object;
                  }
                  else {
                        return null;
                  }
            }
            else {
                  return false;
            }
      }
     
      function __destruct(){
            @mysql_free_result($this->resource);
            @mysql_close($this->conexion);
      }
}
?>


Si notamos, el constructor es privado. Esto es para asegurarnos de que la clase se instancie desde dentro de sí misma. Es decir, al ejecutar el método DataBase::getInstance()  llamamos al constructor y creamos una única instancia de DataBase. Si volvemos a ejecutar ese método y la clase ya ha sido instanciada antes, entonces nos devolverá la instancia. Eso es el objetivo del patrón Singleton.

Vemos entonces como hacer una conexión, ejecutar una consulta y mostrar los resultados. Se asume que los parámetros de conexión como el host, el nombre de usuario y demás se especifican directamente en la clase.

<?php
      require_once 'config.php';
      /* Hacemos la conexión*/
      $db = DataBase::getInstance();
     
      // Supongamos que tenemos una tabla de usuarios
      // Hacemos la consulta:
      $db->setQuery('SELECT `login`,`nombres`,`apellidos`,`privilegio` FROM `usuario`');
     
      // La ejecutamos y al mismo tiempo obtenemos un arreglo de objetos
      // con los campos especificados en la consulta como propiedades.
      $usuarios = $db->loadObjectList();
     
     
      echo 'Informacion de la Base de Datos bdbeauty'; echo '<br />'; echo '<br />'; echo '<br />';
     
      // Los imprimimos directamente en pantalla...
      foreach($usuarios as $usuario){
           
            echo 'Login: '.$usuario->login; echo '<br />';
            echo 'Nombres: '.$usuario->nombres;echo '<br />';
            echo 'Apellidos '.$usuario->apellidos;echo '<br />';
            echo 'Privilegio '.$usuario->privilegio;echo '<br />';
            echo '<br />';
     
      }
?>


De manera que podemos ver que con esta implementación logramos Se tiene controlada la creación de objetos y podremos además disminuir el uso de memoria al tener una sola instancia que se usa en todo el contexto de la aplicación. Evita que nuestro sistema, en un momento dado, tenga innumerables y descontroladas conexiones a la base de datos, consumiendo recursos.