Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Múltiples conexiones a la BD con Code Igniter

Estas en el tema de Múltiples conexiones a la BD con Code Igniter en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Buenos días a todos (o tardes/noches según país). Trabajando con Code Igniter he llegado a un punto en el que las conexiones con la base ...
  #1 (permalink)  
Antiguo 06/06/2013, 01:21
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Múltiples conexiones a la BD con Code Igniter

Buenos días a todos (o tardes/noches según país).

Trabajando con Code Igniter he llegado a un punto en el que las conexiones con la base de datos me suponen un problema. Tengo unas 4 o 5 conexiones configuradas.

El problema que tengo es el siguiente. En muchos de mis modelos me estaba conectando en el contructor del modelo. A fin de cuentas cargar un modelo significa que voy a usar la base de datos... hasta ahora.

He creado modelos "pojo" para facturas y sus líneas. Tengo un array lleno de facturas tipo "Modelo_factura" y dentro de estos una variable privada con un array de lineas tipo "Modelo_linea". Claro, si voy conectando en el constructor me puedo encontrar con 600 conexiones simultáneas.

Pero también querría hacer un $factura->guardar(); por lo que cada una de estos modelos si que deberia tener conexion. Pero la misma!

Además, si voy creando la conexion desde fuera y se la envío a los modelos veo que code igniter asocia $this->db a la última cargada, así que si tengo que mezclar varias conexiones se va sobreescribiendo el valor de $this->db y tengo que ir cambiándolo.

En fin que no veo nada claro como hacer esto bien. Quizá mis clases POJO no deberían estar en models y no deberían tener conexiones?

Además, no entiendo qué hace $this->load->model('Nombre_modelo'). Pensaba que solo "incluía" la clase, pero veo que también la instancia en $this->Nombre_modelo.

Cuanto más conozco más ignorante soy.

Mi único intento de solución fué extender CodeIgniter.php con una clase propia con $db1, $db2, $db3... y luego desde cualquier sitio usar $db1 para la db1, la 2 para la 2... pero resulta que los modelos no tienen origen en CodeIgniter.php... así que tampoco me sirvió.

¿Algún consejo para manejar estas conexiones?

Es que creo que lo lógico sería aprovechar los modelos como pojos si están bien hechos, porque sino sería duplicar la información.

Por lo pronto lo he "arreglado" así. En el fichero databases incluyo al final esta clase:
Código PHP:
Ver original
  1. <?php
  2. if ( ! class_exists ('Conn'))
  3. {
  4.     Class Conn
  5.     {
  6.         static $gestion;
  7.         static $subversion;
  8.         static $trackings;
  9.         static $proveedores;
  10.  
  11.         static function conectarGestion($conexion)
  12.         {
  13.             if (!self::$gestion)
  14.                 self::$gestion = $conexion;
  15.         }
  16.  
  17.         static function conectarSubversion($conexion)
  18.         {
  19.             if (!self::$subversion)
  20.                 self::$subversion = $conexion;
  21.         }
  22.  
  23.         static function conectarTrackings($conexion)
  24.         {
  25.             if (!self::$trackings)
  26.                 self::$trackings = $conexion;
  27.         }
  28.  
  29.     }
  30. }

Y luego para usarlo pues:
Código PHP:
Ver original
  1. Conn::conectarGestion($dsn);
  2. $res = Conn::gestion->query("SELECT nombre FROM clientes")->result_query();

Lo veis correcto o es una burrada?


Al final me ha quedado así. Aunque sigo sin saber si estoy comiento algún error grave. Funcionar funciona eso sí.
Código PHP:
Ver original
  1. <?php
  2.  
  3. if ( ! class_exists ('Conexiones'))
  4. {
  5.     /**
  6.      * Class Conexiones
  7.      * La utiliza la clase Conn
  8.      * NO USAR MANUALMENTE
  9.      */
  10.     Class Conexiones extends CI_Controller
  11.     {      
  12.         public function getGestion()
  13.         {
  14.             return $this->load->database('gestion', TRUE);
  15.         }        
  16.         public function getSubversion()
  17.         {
  18.             return $this->load->database('subversion', TRUE);
  19.         }
  20.         public function getTrackings()
  21.         {
  22.             return $this->load->database('trackings', TRUE);
  23.         }
  24.         public function getProveedores()
  25.         {
  26.             return $this->load->database('proveedores', TRUE);
  27.         }
  28.     }
  29. }
  30. if ( ! class_exists ('Conn'))
  31. {
  32.     /**
  33.      * Class Conn
  34.      */
  35.     Class Conn
  36.     {
  37.         /**
  38.          * Contiene una instancia de la clase conexiones
  39.          * @var Conexiones $conexiones
  40.          */
  41.         private static $conexiones;
  42.  
  43.         static $gestion;
  44.         static $subversion;
  45.         static $trackings;
  46.         static $proveedores;
  47.  
  48.         static private function compruebaConexiones()
  49.         {
  50.             if (!self::$conexiones)
  51.                 self::$conexiones = new Conexiones();
  52.         }
  53.  
  54.         /**
  55.          * @return void
  56.          */
  57.         static function conectarGestion()
  58.         {
  59.             self::compruebaConexiones();
  60.  
  61.             if (!self::$gestion)
  62.                 self::$gestion = self::$conexiones->getGestion();
  63.         }      
  64.  
  65.         static function conectarProveedores()
  66.         {
  67.             self::compruebaConexiones();
  68.             if (!self::$proveedores)
  69.                 self::$proveedores = self::$conexiones->getProveedores();
  70.         }
  71.  
  72.         static function conectarSubversion()
  73.         {
  74.             self::compruebaConexiones();
  75.             if (!self::$subversion)
  76.                 self::$subversion = self::$conexiones->getSubversion();
  77.         }
  78.  
  79.         static function conectarTrackings()
  80.         {
  81.             self::compruebaConexiones();
  82.             if (!self::$trackings)
  83.                 self::$trackings = self::$conexiones->getTrackings();
  84.         }
  85.  
  86.         /**
  87.          * @return mixed
  88.          */
  89.         public static function getProveedores()
  90.         {
  91.             if (!self::$proveedores) self::conectarProveedores();
  92.             return self::$proveedores;
  93.         }
  94.  
  95.         /**
  96.          * @return mixed
  97.          */
  98.         public static function getGestion()
  99.         {
  100.             if (!self::$proveedores) self::conectarGestion();
  101.             return self::$gestion;
  102.         }
  103.  
  104.  
  105.         /**
  106.          * @return mixed
  107.          */
  108.         public static function getSubversion()
  109.         {
  110.             if (!self::$proveedores) self::conectarSubversion();
  111.             return self::$subversion;
  112.         }
  113.  
  114.         /**
  115.          * @return mixed
  116.          */
  117.         public static function getTrackings()
  118.         {
  119.             if (!self::$proveedores) self::conectarTrackings();
  120.             return self::$trackings;
  121.         }
  122.  
  123.     }
  124.  
  125. }

Y para utilizarlo sólo tengo que poner esto en cualquier sitio:
Conn::getGestion()->query("SELECT nombre FROM clientes")->result();

Y ya se encarga de conectar si es necesario y de devolver la conexión adecuada.

Si le sirve a alguien estupendo. Me falta hacer pruebas y ver si funciona correctamente.

Última edición por alyciashape; 06/06/2013 a las 04:10
  #2 (permalink)  
Antiguo 06/06/2013, 10:27
Avatar de abimex
Colaborador
 
Fecha de Ingreso: marzo-2007
Ubicación: ~
Mensajes: 751
Antigüedad: 17 años, 2 meses
Puntos: 137
Respuesta: Múltiples conexiones a la BD con Code Igniter

podrias usar injeccion de dependencias para meterle el objeto DB a tus clases, o podrias usar algun ORM e integrarlo a codeigniter
nunca me ha gustado codeigniter :P
__________________
>> abimaelmartell.com
  #3 (permalink)  
Antiguo 08/06/2013, 13:25
Avatar de destor77  
Fecha de Ingreso: noviembre-2004
Ubicación: Gálvez, Santa Fe, Argentina
Mensajes: 2.654
Antigüedad: 19 años, 6 meses
Puntos: 43
Respuesta: Múltiples conexiones a la BD con Code Igniter

primero que nada no entendi a que hacias referencia con "pojo" si tiene que usar muchas base de datos creo que el problema esta ahí deberias tener una sola con miles de tabla de ultima. Pero bueno eso es otro tema. Yo tuve que usar una db para un sistema que hice y que luego me pidieron que extrajera datos de un oscommerce, tras lidiar un poco lo logre de la siguiente manera:

mi modelo que apunta a la db oscommerce:
Código PHP:
Ver original
  1. class Productos_model extends MY_Model
  2. {
  3.     private $db2 = null;
  4.  
  5.     function __construct()
  6.     {
  7.         parent::__construct();
  8.  
  9.         $this->tabla = 'products';
  10.         $this->primary_key = 'products_id';
  11.         $this->db2 = $this->load->database('wp',TRUE);
  12.     }
  13.  
  14.     public function todos($categoria_id = null){
  15.          $this->db2->select(" p.products_id, pd.products_name,p.manufacturers_id, p.products_price, p.products_tax_class_id");
  16.         $this->db2->join('specials s',"p.products_id = s.products_id",'left');
  17.         $this->db2->join('products_to_categories p2c',"p.products_id = p2c.products_id",'left');
  18.         $this->db2->join('products_description pd',"pd.products_id = p2c.products_id",'left');
  19.         $this->db2->join('manufacturers m',"p.manufacturers_id = m.manufacturers_id",'left');
  20.         $this->db2->join('products_to_stores ps',"ps.products_id = p.products_id",'left');
  21.         $this->db2->where('ps.stores_id','1');
  22.         $this->db2->where('p.products_status','1');
  23.         if($categoria_id){
  24.             $this->db2->where('p2c.categories_id',$categoria_id);
  25.         }
  26.  
  27.         $query = $this->db2->get($this->tabla.' p');
  28.         return $query->result_array();
  29.     }
  30.  
  31.     public function buscar_producto($id){
  32.         $this->db2->select(" p.products_id, pd.products_name,p.manufacturers_id, p.products_price, p.products_tax_class_id,t.tax_rate,s.specials_new_products_price");
  33.         $this->db2->join('specials s',"p.products_id = s.products_id",'left');
  34.         $this->db2->join('products_to_categories p2c',"p.products_id = p2c.products_id",'left');
  35.         $this->db2->join('products_description pd',"pd.products_id = p2c.products_id",'left');
  36.         $this->db2->join('manufacturers m',"p.manufacturers_id = m.manufacturers_id",'left');
  37.         $this->db2->join('products_to_stores ps',"ps.products_id = p.products_id",'left');
  38.         $this->db2->join('tax_rates t',"t.tax_rates_id = p.products_tax_class_id",'left');
  39.         $this->db2->where('ps.stores_id','1');
  40.         $this->db2->where('p.products_status','1');
  41.         $this->db2->where('p.products_id',$id);
  42.         $query = $this->db2->get($this->tabla.' p');
  43.  
  44.         $result = $query->result_array();
  45.         return $result[0];
  46.     }
  47.  
  48. }

modelo que apunta a la db de mi sistema:
Código PHP:
Ver original
  1. <?php
  2. /**
  3.  * Creado por Onírico Sistemas.
  4.  * Usuario: onirico
  5.  * Fecha: 22/04/13
  6.  * Hora: 14:27
  7.  *
  8.  */
  9. class Empresas_model extends MY_Model
  10. {
  11.     function __construct()
  12.     {
  13.         parent::__construct();
  14.  
  15.         $this->tabla = 'empresas';
  16.         $this->primary_key = 'empresa_id';
  17.     }
  18.  
  19.     public function todos($order_by = 'empresa_id', $order = 'desc',$like = null){
  20.         $this->db->order_by($order_by,$order);
  21.         if($like){
  22.             foreach($like as $clave => $valor){
  23.                 $this->db->like($clave,$valor,'after');
  24.             }
  25.             $array = array_keys($like);
  26.             foreach($array as $key){
  27.                 if($order == 'des'){
  28.                     $order = 'desc';
  29.                 }
  30.                 $this->db->order_by($order_by,$order);
  31.             }
  32.         }
  33.         else{
  34.             if($order == 'des'){
  35.                 $order = 'desc';
  36.             }
  37.             $this->db->order_by($order_by,$order);
  38.         }
  39.         $query = $this->db->get($this->tabla);
  40.  
  41.         return $query->result_array();
  42.     }
  43.  
  44.     public function empresa_usuario($id){
  45.         $this->db->select('e.*,p.nombre AS pais');
  46.         $this->db->join('pais p','p.id = e.pais');
  47.         $this->db->where('empresa_id',$id);
  48.  
  49.         $query = $this->db->get($this->tabla.' e');
  50.  
  51.         return $query->result_array();
  52.     }
  53. }

archivo de configuracion de las base de datos:
Código PHP:
Ver original
  1. caching
  2. |   ['cachedir'] The path to the folder where cache files should be stored
  3. |   ['char_set'] The character set used in communicating with the database
  4. |   ['dbcollat'] The character collation used in communicating with the database
  5. |                NOTE: For MySQL and MySQLi databases, this setting is only used
  6. |                as a backup if your server is running PHP < 5.2.3 or MySQL < 5.0.7
  7. |                (and in table creation queries made with DB Forge).
  8. |                There is an incompatibility in PHP with mysql_real_escape_string() which
  9. |                can make your site vulnerable to SQL injection if you are using a
  10. |                multi-byte character set and are running versions lower than these.
  11. |                Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
  12. |   ['swap_pre'] A default table prefix that should be swapped with the dbprefix
  13. |   ['autoinit'] Whether or not to automatically initialize the database.
  14. |   ['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
  15. |                           - good for ensuring strict SQL while developing
  16. |
  17. | The $active_group variable lets you choose which connection group to
  18. | make active.  By default there is only one group (the 'default' group).
  19. |
  20. | The $active_record variables lets you determine whether or not to load
  21. | the active record class
  22. */
  23.  
  24. $active_group = 'default';
  25. $active_record = TRUE;
  26.  
  27. if(ENVIRONMENT  == 'development'){
  28.     $db['default']['hostname'] = 'localhost';
  29.     $db['default']['username'] = 'root';
  30.     $db['default']['password'] = '';
  31.     $db['default']['database'] = 'duchamania';
  32.     $db['default']['dbdriver'] = 'mysql';
  33.     $db['default']['dbprefix'] = '';
  34.     //conexion a la otra base de datos
  35.     $db['wp']['hostname'] = 'localhost';
  36.     $db['wp']['username'] = 'root';
  37.     $db['wp']['password'] = '';
  38.     $db['wp']['database'] = 'mundoba_osc2';
  39.     $db['wp']['dbdriver'] = 'mysql';
  40.     $db['wp']['dbprefix'] = '';
  41.     $db['wp']['pconnect'] = FALSE;
  42.     $db['wp']['db_debug'] = TRUE;
  43.     $db['wp']['cache_on'] = FALSE;
  44.     $db['wp']['cachedir'] = '';
  45.     $db['wp']['char_set'] = 'utf8';
  46.     $db['wp']['dbcollat'] = 'utf8_general_ci';
  47.     $db['wp']['swap_pre'] = '';
  48.     $db['wp']['autoinit'] = TRUE;
  49.     $db['wp']['stricton'] = FALSE;
  50. }
  51. else{
  52.     $db['default']['hostname'] = 'localhost';
  53.     $db['default']['username'] = 'xxx_78';
  54.     $db['default']['password'] = 'xxxx';
  55.     $db['default']['database'] = 'mundoba_presup';
  56.     $db['default']['dbdriver'] = 'mysql';
  57.     $db['default']['dbprefix'] = '';
  58. }
  59.  
  60. $db['default']['pconnect'] = FALSE;
  61. $db['default']['db_debug'] = TRUE;
  62. $db['default']['cache_on'] = FALSE;
  63. $db['default']['cachedir'] = '';
  64. $db['default']['char_set'] = 'utf8';
  65. $db['default']['dbcollat'] = 'utf8_general_ci';
  66. $db['default']['swap_pre'] = '';
  67. $db['default']['autoinit'] = TRUE;
  68. $db['default']['stricton'] = FALSE;

y despues en el controlador llamos los modelos asi:
Código PHP:
Ver original
  1. class Presupuestos extends CI_Controller
  2. {
  3.     private $session_group;
  4.  
  5.     public function __construct()
  6.     {
  7.         parent::__construct();
  8.         //aca instancio los modelos del osccomerce
  9.         $this->load->model('Categorias_model','categorias');
  10.         $this->load->model('Subcategoria_model','subcategorias');
  11.         $this->load->model('Productos_model','productos');
  12.  
  13.         // van mis modelos
  14.         $this->load->model('Usuarios_model','usuarios');
  15.         $this->load->model('Numeros_model','numeros');
  16.         $this->load->model('Clientes_model','clientes');
  17.         $this->load->model('Clientes_Direcciones_model','clientes_direcciones');
  18.         $this->load->model('Presupuesto_model','presupuesto');
  19.         $this->load->model('Pedidos_model','pedidos');
  20.         $this->load->model('Facturas_model','facturas');
  21.         $this->load->model('Item_model','items');
  22.         $this->load->model('Empresas_model','empresas');
  23.         $this->load->model('Paises_model','pais');

lo que hace $this->load->model('Nombre_modelo'). es buscar el modelo por el nombre que pones en los parentesis en la carpeta model e instanciarlo para poder usarlo.
Yo en tu caso creacia x cantidad de conexiones en el archivo de configuracion y en cada modelo las vas llamando cuando sea necesario.
Saludos

Etiquetas: codeigniter
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 02:13.