Foros del Web » Programando para Internet » PHP »

Duda con PDO y mi clase

Estas en el tema de Duda con PDO y mi clase en el foro de PHP en Foros del Web. Porque no mejor heredas tu clase Db de la clase de PDO y te quitas así los problemas de usar return ya que a la ...

  #31 (permalink)  
Antiguo 01/09/2010, 13:47
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Porque no mejor heredas tu clase Db de la clase de PDO y te quitas así los problemas de usar return ya que a la hora de en tu constructor regresar otro objeto no se puede.

Saludos.
  #32 (permalink)  
Antiguo 01/09/2010, 14:34
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Porque no mejor heredas tu clase Db de la clase de PDO y te quitas así los problemas de usar return ya que a la hora de en tu constructor regresar otro objeto no se puede.

Saludos.
No se como realizar la herencia de forma correcta, tengo una idea pero no está completa y mucho menos buena...

Código PHP:
Ver original
  1. class DB extends PDO {
  2.     private $_username;
  3.     private $_password;
  4.     private $_host;
  5.     private $_db;
  6.     private $_conexion;
  7.    
  8.     public function __construct($dsn,$username=null,$password=null,$driver_options=null)
  9.    {
  10.         $config_data = $config->getConfig();
  11.         $this->_username = $config_data['username'];
  12.         $this->_password = $config_data['password'];
  13.         $this->_host = $config_data['host'];
  14.         $this->_db = $config_data['db'];
  15.    
  16.       parent::__construct($dsn, $this->_username, $this->_password, $driver);
  17.    }
  18.  
  19. }

Si sirve de referencia tengo una herencia de otro post que funciona muy bien. ¿Se puede aprovechar?

Código PHP:
Ver original
  1. <?php
  2. /*
  3.     CLASE EXTENDIDA DE PDO para contar el número de consultas que se realizan
  4. */
  5. class CountPDO extends PDO
  6. {
  7.     private $_queryCount = 0;
  8.    
  9.     public function query()
  10.     {
  11.         $this->_increaseQueryCount();
  12.         $args = func_get_args();
  13.        
  14.         return call_user_func_array(array('parent', 'query'), $args);
  15.     }
  16.    
  17.     public function prepare($statement, $driver_options = array())
  18.     {
  19.         $this->_increaseQueryCount();
  20.         return parent::prepare($statement, $driver_options);
  21.     }
  22.    
  23.     private function _increaseQueryCount()
  24.     {
  25.         $this->_queryCount++;
  26.     }
  27.    
  28.     public function getQueryCount()
  29.     {
  30.         return $this->_queryCount;
  31.     }
  32.     public function ResetCount()
  33.     {
  34.         $this->_queryCount = 0;
  35.     }
  36. }
  37. ?>

Gracias de antemano
  #33 (permalink)  
Antiguo 01/09/2010, 14:52
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Te recomiendo leer un poco sobre que es y como funciona la herencia, si solo le vas a pasar un parámetro que es el config tienes que declararlo de esa forma.
  #34 (permalink)  
Antiguo 01/09/2010, 15:54
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Te recomiendo leer un poco sobre que es y como funciona la herencia, si solo le vas a pasar un parámetro que es el config tienes que declararlo de esa forma.
Si he leído y visto tutoriales sobre la herencia, se trata de "sobreescribir" métodos que existen en la clase "padre".

Pero no se seguir

Se supone que estoy redeclarando el constructor de la clase PDO para que sea como hemos especificado anteriormente, que sea capaz de leer la variables del fichero .ini

Y luego debe existir por algún lado la conexión PDO que no sé si se tiene que definir a parte tal y como está o se necesita algo más?

Código PHP:
Ver original
  1. class DB extends PDO {
  2.     private $_username;
  3.     private $_password;
  4.     private $_host;
  5.     private $_db;
  6.     private $_conexion;
  7.    
  8.     public function __construct(Config $config)
  9.     {
  10.         $config_data = $config->getConfig();
  11.         $this->_username = $config_data['username'];
  12.         $this->_password = $config_data['password'];
  13.         $this->_host = $config_data['host'];
  14.         $this->_db = $config_data['db'];
  15.        
  16.         return $this->Conectar();
  17.     }
  18.    
  19.     private function Conectar(){
  20.         try {
  21.             $this->_conexion = new PDO("mysql:host=$this->_host;dbname=$this->_db", $this->_username, $this->_password);
  22.             // echo a message saying we have connected
  23.             echo 'Connected to database';
  24.         }
  25.         catch(PDOException $e){
  26.             echo $e->getMessage();
  27.         }
  28.         return $this->_conexion;
  29.     }
  30. }
  #35 (permalink)  
Antiguo 01/09/2010, 17:51
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Estas aplicando muy mal la herencia, mira este ejemplo:
Código PHP:
Ver original
  1. class Padre
  2. {
  3.           public function __construct($var1, $var2)
  4.          {
  5.                  // Esta clase acepta dos parámetros $var1 y $var2
  6.           }
  7. }
  8.  
  9. class Hija extends Padre
  10. {
  11.          public function __construct($var)
  12.          {
  13.                   // como la clase padre requiere 2 valores, le pasamos el $var de aqui y otro valor que definimos nosotros
  14.                   parent::__construct($var, 2);
  15.           }
  16. }

Si te fijas, al crear una instancia de Hija, es una instancia de Padre y le estamos pasando al constructor de padre los datos que quiere, tu tienes que hacer lo mismo una clase Db que acepte de parámetro un objeto config y que internamente llame al constructor de su clase padre con los datos que requiere.

Saludos.
  #36 (permalink)  
Antiguo 01/09/2010, 18:26
Avatar de portalmana  
Fecha de Ingreso: septiembre-2007
Ubicación: Montevideo-Uruguay
Mensajes: 633
Antigüedad: 16 años, 6 meses
Puntos: 80
Respuesta: Duda con PDO y mi clase

Cuando hice un cursillo de java nos dieron una lista aditiva de cuando se podría heredar, como una guía de cuando esta bien que se herede y que no se use por el mero hecho de reutilizar código...

+ Cuando está seguro de que cumple la relación ... es un ...
p.ej.: un zafral no es un empleado (le faltan beneficios, no tiene aumentos de sueldo, etc.)

+ Cuando está seguro de que toda la funcionalidad heredada tiene sentido
p.ej.: si “Documento” incluye un método “entregarMercadería” los “Recibos” no podrán heredar de dicha clase

+ Si la superclase es abstracta se heredarán varias subclases diferentes.
p.ej.: si tubieramos una única clase de Mascota y fuera Perro no tendría sentido que se separaran en dos clases diferentes (Mascota – Perro).

+ Cuando el cuadro de clases obtenido tienen funcionalidades diferentes
(respecto a la superclase y entre subclases)
p.ej.: Si todas las especializaciones de Mascota “ladraran”, “hicieranPiruetas”
y se “rascaranLasPulgas”, aunque fueran “Iguanas”, podrían representarse con la
misma clase agregando un atributo “especie”.

o Cuando piensa que tiene una especialización y nadie le dice que no (¡¡¡ buena suerte !!!)

Y un enlace muy bueno de Enrique

Saludos
__________________
"La imaginación es más importante que el conocimiento. El conocimiento es limitado, mientras que la imaginación no" -- A.Einstein
objetivophp.com,twitter.com/objetivophp
  #37 (permalink)  
Antiguo 01/09/2010, 23:55
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Estas aplicando muy mal la herencia, mira este ejemplo:
Código PHP:
Ver original
  1. class Padre
  2. {
  3.           public function __construct($var1, $var2)
  4.          {
  5.                  // Esta clase acepta dos parámetros $var1 y $var2
  6.           }
  7. }
  8.  
  9. class Hija extends Padre
  10. {
  11.          public function __construct($var)
  12.          {
  13.                   // como la clase padre requiere 2 valores, le pasamos el $var de aqui y otro valor que definimos nosotros
  14.                   parent::__construct($var, 2);
  15.           }
  16. }

Si te fijas, al crear una instancia de Hija, es una instancia de Padre y le estamos pasando al constructor de padre los datos que quiere, tu tienes que hacer lo mismo una clase Db que acepte de parámetro un objeto config y que internamente llame al constructor de su clase padre con los datos que requiere.

Saludos.
Así mejor? sobreescribo el constructor de PDO y luego dentro de él llamo a la clase padre con los datos que requiere mas el nuevo parámetro?

Código PHP:
Ver original
  1. class DB extends PDO {
  2.     private $_username;
  3.     private $_password;
  4.     private $_host;
  5.     private $_db;
  6.     private $_conexion;
  7.    
  8.     public function __construct(Config $config)
  9.     {
  10.         $config_data = $config->getConfig();
  11.         $this->_username = $config_data['username'];
  12.         $this->_password = $config_data['password'];
  13.         $this->_host = $config_data['host'];
  14.         $this->_db = $config_data['db'];
  15.        
  16.         parent::__construct($dsn, $username="", $password="", $driver_options=array(), Config $config);
  17.     }
  18. }
  #38 (permalink)  
Antiguo 02/09/2010, 01:20
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

¿ O debería llamar al padre pasandole lo parámetros originales, es decir sin el Config?

parent::__construct($dsn, $username="", $password="", $driver_options=array());
  #39 (permalink)  
Antiguo 02/09/2010, 08:33
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Debes de llamar al constructor pasandole los parámetros que tu quieras definir, te dejo otro ejemplo más claro:
Código PHP:
Ver original
  1. class Auto
  2. {
  3.          public function __construct($marca, $color)
  4.          {}
  5. }
  6.  
  7. class VWAzul
  8. {
  9.          public function __construct() // nota: no hay parámetros
  10.          {
  11.                 $marca = 'VW';
  12.                 $color = 'Azul';
  13.                 parent::__construct($marca, $color);
  14.          }
  15. }

Saludos.
  #40 (permalink)  
Antiguo 02/09/2010, 09:03
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Debes de llamar al constructor pasandole los parámetros que tu quieras definir, te dejo otro ejemplo más claro:
Código PHP:
Ver original
  1. class Auto
  2. {
  3.          public function __construct($marca, $color)
  4.          {}
  5. }
  6.  
  7. class VWAzul
  8. {
  9.          public function __construct() // nota: no hay parámetros
  10.          {
  11.                 $marca = 'VW';
  12.                 $color = 'Azul';
  13.                 parent::__construct($marca, $color);
  14.          }
  15. }

Saludos.
Ajam, entonces esta es la manera correcta de heredar en este caso, no?

Código PHP:
Ver original
  1. class DB extends PDO {
  2.     private $_username;
  3.     private $_password;
  4.     private $_host;
  5.     private $_db;
  6.     private $_conexion;
  7.    
  8.     public function __construct(Config $config)
  9.     {
  10.         $config_data = $config->getConfig();
  11.         $this->_username = $config_data['username'];
  12.         $this->_password = $config_data['password'];
  13.         $this->_host = $config_data['host'];
  14.         $this->_db = $config_data['db'];
  15.        
  16.         parent::__construct($dsn, $username="", $password="", $driver_options=array());
  17.     }
  18. }

Utilizo esta llamada porque es la que aparece en la documentacion de PDO...
parent::__construct($dsn, $username="", $password="", $driver_options=array());

¿Es correcto?

Gracias de antemano!
  #41 (permalink)  
Antiguo 02/09/2010, 09:31
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

No, es incorrecto, por favor medita el ejemplo que te puse, al tu hacer esto:
Código PHP:
Ver original
  1. function foo($bar) {
  2.  
  3. }
  4.  
  5. foo($bar = "");

El interprete de PHP ve primero la asignacion dentro del paréntesis $bar = "" y asigna a $bar un valor vacio, posterioremente llama a foo.

Te recomiendo leas un libro de PHP básico para que entiendes como es que se tienen que llamar las funciones y como hacer el paso de parámetros.

Saludos!
  #42 (permalink)  
Antiguo 02/09/2010, 09:42
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
No, es incorrecto, por favor medita el ejemplo que te puse, al tu hacer esto:
Código PHP:
Ver original
  1. function foo($bar) {
  2.  
  3. }
  4.  
  5. foo($bar = "");

El interprete de PHP ve primero la asignacion dentro del paréntesis $bar = "" y asigna a $bar un valor vacio, posterioremente llama a foo.

Te recomiendo leas un libro de PHP básico para que entiendes como es que se tienen que llamar las funciones y como hacer el paso de parámetros.

Saludos!

Creo que ahora te entiendo, precisamente, eso era lo que no me cuadraba, que tuviese que pasarle esos parametros:

parent::__construct($dsn, $username="", $password="", $driver_options=array());

Sino mas bien los que toca que son ni mas ni menos que los que aparecen aqui, verdad?

$this->_username = $config_data['username'];
$this->_password = $config_data['password'];
$this->_host = $config_data['host'];
$this->_db = $config_data['db'];


Sin embargo, mi duda es que no se poner en su sitio la variable $dsn, segun el ejemplo de PDO debería tener esta forma

'mysql:host=127.0.0.1;dbname=codelab'

Debería hacerlo así, declarar una variable llamada $_dsn;

$this->_$dsn="mysql:host=$this->_host;dbname=$this->_db";

parent::__construct($this->_$dsn, $this->_username, $this->_password);


Mejor? :D
  #43 (permalink)  
Antiguo 02/09/2010, 10:57
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Exacto ahora sí, te digo sería mucho mejor para ti y para que aprendas más que leas un libro de PHP, así puedes entender como funciona la sintaxis y como crear funciones y declarar los valores.

Saludos.
  #44 (permalink)  
Antiguo 02/09/2010, 11:49
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Exacto ahora sí, te digo sería mucho mejor para ti y para que aprendas más que leas un libro de PHP, así puedes entender como funciona la sintaxis y como crear funciones y declarar los valores.

Saludos.
Entonces no hace falta que utilice el método Conectar() dentro de la clase no?

Código PHP:
Ver original
  1. private function Conectar(){
  2.         try {
  3.             $this->_conexion = new PDO("mysql:host=$this->_host;dbname=$this->_db", $this->_username, $this->_password);
  4.             // echo a message saying we have connected
  5.             echo 'Connected to database';
  6.         }
  7.         catch(PDOException $e){
  8.             echo $e->getMessage();
  9.         }
  10.         return $this->_conexion;
  11.     }

Con esto sería suficiente no?

<?php

Código PHP:
Ver original
  1. class DB extends PDO {
  2.     private $_username;
  3.     private $_password;
  4.     private $_host;
  5.     private $_db;
  6.     private $_conexion;
  7.     private $_dsn;
  8.  
  9.     public function __construct(Config $config)
  10.     {
  11.         $config_data = $config->getConfig();
  12.         $this->_username = $config_data['username'];
  13.         $this->_password = $config_data['password'];
  14.         $this->_host = $config_data['host'];
  15.         $this->_db = $config_data['db'];
  16.         $this->_dsn="mysql:host=$this->_host;dbname=$this->_db";
  17.        
  18.         try {
  19.             parent::__construct($this->_dsn, $this->_username, $this->_password);
  20.             // echo a message saying we have connected
  21.             //echo 'Connected to database';
  22.         }
  23.         catch(PDOException $e){
  24.             echo $e->getMessage();
  25.             exit;
  26.         }
  27.        
  28.     }
  29. }
  30.  
  31. ?>



ejemplo1.php

Código PHP:
Ver original
  1. <?php
  2.  
  3. require('config_reader.php');
  4. require('db.php');
  5. require('registry.php');
  6.  
  7. class Categoria{
  8.     private $nombreCategoria;
  9.    
  10.     // Listar todas las categorias de la base de datos
  11.     public function listarCategorias($db){
  12.         $query = "SELECT nombre FROM categorias";
  13.         $comando = $db->prepare($query);
  14.         $comando->execute();
  15.  
  16.         while( $datos = $comando->fetch() ) {
  17.         // Imprimimos resultados
  18.         echo $datos[0].'<br />';
  19.         }
  20.     }
  21.    
  22.     // Listar todas los partidos de la base de datos
  23.     public function listarPartidos($db){
  24.         $query = "SELECT home FROM partidos";
  25.         $comando = $db->prepare($query);
  26.         $comando->execute();
  27.  
  28.         while( $datos = $comando->fetch() ) {
  29.         // Imprimimos resultados
  30.         echo $datos[0].'<br />';
  31.         }
  32.     }
  33.    
  34. }
  35.  
  36. //Cargo los datos del fichero .ini
  37. $config_slave = new Config('params_slave.ini');
  38. $config_master = new Config('params_master.ini');
  39.  
  40. //Creo el objeto de la base de datos
  41. $db_slave = new db($config_slave);
  42. $db_master = new db($config_master);
  43.  
  44. //Guardo las instancias diferentes con Registry
  45. Registry::save('db_slave', $db_slave);
  46. Registry::save('db_master', $db_master);
  47.  
  48. //Recupero las instancias con Registry
  49. $db_slave=Registry::get('db_slave');
  50. $db_master=Registry::get('db_master');
  51.  
  52. $cat= new Categoria();
  53. $cat->listarCategorias($db_slave); // Leo de la BBDD slave
  54. $cat->listarPartidos($db_master); // Ejemplo leyendo de otra BBDD master
  55.  
  56. ?>
  #45 (permalink)  
Antiguo 02/09/2010, 13:48
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Así es, aunque como tip, yo no manejaría la excepcion de conectar dentro de tu clase DB, se la dejaría a la clase donde la implementas para que tengas un mejor control del flujo de tu aplicación.

Saludos.
  #46 (permalink)  
Antiguo 02/09/2010, 14:11
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Así es, aunque como tip, yo no manejaría la excepcion de conectar dentro de tu clase DB, se la dejaría a la clase donde la implementas para que tengas un mejor control del flujo de tu aplicación.

Saludos.
Es decir, dentro de cada clase que implemente, en este ejemplo Categorias() y Partidos()?

La clase MyPDO.class.php la dejarías así??

Código PHP:
Ver original
  1. <?php
  2. /*
  3.     CLASE EXTENDIDA DE PDO:
  4.     - Cuenta el número de consultas que se realizan
  5.     - Utiliza la carga los datos de conexión desde la clase Config
  6. */
  7. class MyPDO extends PDO {
  8.     private $_username;
  9.     private $_password;
  10.     private $_host;
  11.     private $_db;
  12.     private $_conexion;
  13.     private $_dsn;
  14.     private $_queryCount = 0;
  15.    
  16.     public function __construct(Config $config)
  17.     {
  18.         $config_data = $config->getConfig();
  19.         $this->_username = $config_data['username'];
  20.         $this->_password = $config_data['password'];
  21.         $this->_host = $config_data['host'];
  22.         $this->_db = $config_data['db'];
  23.         $this->_dsn="mysql:host=$this->_host;dbname=$this->_db";
  24.        
  25.         parent::__construct($this->_dsn, $this->_username, $this->_password);
  26.     }
  27.    
  28.     public function query()
  29.     {
  30.         $this->_increaseQueryCount();
  31.         $args = func_get_args();
  32.        
  33.         return call_user_func_array(array('parent', 'query'), $args);
  34.     }
  35.    
  36.     public function prepare($statement, $driver_options = array())
  37.     {
  38.         $this->_increaseQueryCount();
  39.         return parent::prepare($statement, $driver_options);
  40.     }
  41.    
  42.     private function _increaseQueryCount()
  43.     {
  44.         $this->_queryCount++;
  45.     }
  46.    
  47.     public function getQueryCount()
  48.     {
  49.         return $this->_queryCount;
  50.     }
  51.     public function ResetCount()
  52.     {
  53.         $this->_queryCount = 0;
  54.     }
  55. }
  56. ?>

No se de qué manera hacer para controlar la excepción dentro de la clase Categoria()

Código PHP:
Ver original
  1. class Categoria{
  2.     private $_con;
  3.    
  4.     public function __construct($DbConexion){
  5.         try {
  6.             $this->_con=$DbConexion;
  7.             echo "Conectado a la base de datos<br/>";
  8.         }
  9.         catch(PDOException $e){
  10.             echo $e->getMessage();
  11.             echo "Falló la conexión a la base de datos<br/>";
  12.             exit;
  13.         }
  14.     }
  15.    
  16.     // Listar todas las categorias de la base de datos
  17.     public function listarCategorias(){
  18.         $query = "SELECT nombre FROM categorias";
  19.         $comando = $this->_con->prepare($query);
  20.         $comando->execute();
  21.  
  22.         while( $datos = $comando->fetch() ) {
  23.             echo $datos[0].'<br />';
  24.         }
  25.     }
  26. }

¿Puedes indicarme?

Muchas gracias de antemano!

PD: pongo el ejemplo para que se vea de donde sale el parametro que le paso a la clase...

Código PHP:
Ver original
  1. //Cargo los datos del fichero .ini
  2. $config_slave = new Config('params_slave.ini');
  3. $config_master = new Config('params_master.ini');
  4.  
  5. //Creo el objeto de la base de datos
  6. $db_slave = new MyPDO($config_slave);
  7. $db_slave->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);
  8. $db_master = new MyPDO($config_master);
  9. $db_master->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);
  10.  
  11. //Guardo las instancias diferentes con Registry
  12. Registry::save('db_slave', $db_slave);
  13. Registry::save('db_master', $db_master);
  14.  
  15. //Recupero las instancias con Registry
  16. $db_slave=Registry::get('db_slave');
  17. $db_master=Registry::get('db_master');
  18.  
  19. // Creo el primer objeto el cual hace una conexion con la BBDD slave
  20. $cat= new Categoria($db_slave);
  21. $cat->listarCategorias();
  22. $cat->listarCategorias();
  23.  
  24. // Creo el segundo objeto el cual hace una conexion con la BBDD master
  25. $par= new Partidos($db_master);
  26. $par->listarPartidos();
  27.  
  28. // Cuenta el total de consultas que hubieron en cada BBDD
  29. echo "Consultas realizadas en BD Slave: ".$db_slave->getQueryCount()."<br/>";
  30. echo "Consultas realizadas en BD Master: ".$db_master->getQueryCount()."<br/>";
  #47 (permalink)  
Antiguo 02/09/2010, 14:26
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Donde implementes me refiero a donde estes usando las clases, por ejemplo:
Código PHP:
Ver original
  1. try {
  2.         $cat= new Categoria();
  3.         $cat->listarCategorias($db_slave); // Leo de la BBDD slave
  4.         $cat->listarPartidos($db_master); // Ejemplo leyendo de otra BBDD master
  5. } catch (PDOException $pe) {
  6.         echo $pe->getMessage();
  7. }

Así puedes controlar mucho mejor el flujo si se ocasiona algún problema o cachar diferentes tipos de excepciones.

Saludos.
  #48 (permalink)  
Antiguo 02/09/2010, 14:54
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Donde implementes me refiero a donde estes usando las clases, por ejemplo:
Código PHP:
Ver original
  1. try {
  2.         $cat= new Categoria();
  3.         $cat->listarCategorias($db_slave); // Leo de la BBDD slave
  4.         $cat->listarPartidos($db_master); // Ejemplo leyendo de otra BBDD master
  5. } catch (PDOException $pe) {
  6.         echo $pe->getMessage();
  7. }

Así puedes controlar mucho mejor el flujo si se ocasiona algún problema o cachar diferentes tipos de excepciones.

Saludos.
Lo he añadido donde me comentas pero es como si no hiciese caso, ya que el mensaje de error que muestra no el "correcto".

Código PHP:
Ver original
  1. try {
  2.     // Creo el primer objeto el cual hace una conexion con la BBDD slave
  3.     $cat= new Categoria($db_slave);
  4.     $cat->listarCategorias(); // Leo de la BBDD slave
  5. } catch(PDOException $e){
  6.     echo $e->getMessage();
  7.     echo "Hubo un error";
  8. }

He modificado el nombre de la base de datos en el fichero de .ini por uno que no existe y me produce el siguiente error:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000] [1049] Unknown database 'code3lab'' in C:\wamp\www\00-laboratorio_test\secciones\class_categorias\Nueva\ ConectarCon2_BD_version2\MyPDO.class.php:25 Stack trace: #0 C:\wamp\www\00-laboratorio_test\secciones\class_categorias\Nueva\ ConectarCon2_BD_version2\MyPDO.class.php(25): PDO->__construct('mysql:host=loca...', 'root', 'jupiter') #1 C:\wamp\www\00-laboratorio_test\secciones\class_categorias\Nueva\ ConectarCon2_BD_version2\ejemplo1.php(59): MyPDO->__construct(Object(Config)) #2 {main} thrown in C:\wamp\www\00-laboratorio_test\secciones\class_categorias\Nueva\ ConectarCon2_BD_version2\MyPDO.class.php on line 25

La linea 25 hace de la clase MyPDO.class.php hace referencia a aquí

parent::__construct($this->_dsn, $this->_username, $this->_password);

¿Por qué no captura correctamente la excepción?
Ademas tengo puesto justo despues de la creación de los objetos de base de datos el setAttribute, por lo que el error tb debería ser diferente no?

$db_slave = new MyPDO($config_slave);
$db_slave->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);
$db_master = new MyPDO($config_master);
$db_master->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);

¿Sabes por qué?
  #49 (permalink)  
Antiguo 02/09/2010, 15:32
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Si te fijas el error ya es que no conoce una db llamada code3lab' (nota que tienes una comilla de más).

Saludos.
  #50 (permalink)  
Antiguo 02/09/2010, 15:45
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Si te fijas el error ya es que no conoce una db llamada code3lab' (nota que tienes una comilla de más).

Saludos.
Pero pensaba que debía ser como el de clase PDO, si elimino el try y catch anterior y se lo pongo a la clase MyPDO así:

Código PHP:
Ver original
  1. public function __construct(Config $config)
  2.     {
  3.         $config_data = $config->getConfig();
  4.         $this->_username = $config_data['username'];
  5.         $this->_password = $config_data['password'];
  6.         $this->_host = $config_data['host'];
  7.         $this->_db = $config_data['db'];
  8.         $this->_dsn="mysql:host=$this->_host;dbname=$this->_db";
  9.         try {  
  10.             parent::__construct($this->_dsn, $this->_username, $this->_password);
  11.         } catch(PDOException $e){
  12.             echo $e->getMessage();
  13.             echo "Hubo un error";
  14.         }
  15.     }

El error es menos agresivo
SQLSTATE[42000] [1049] Unknown database 'code3lab'Hubo un error

Pensaba que quedaría así, pero si me comentas que no, que al poner el try y catch en:

Código PHP:
Ver original
  1. try {
  2.         $cat= new Categoria();
  3.         $cat->listarCategorias($db_slave); // Leo de la BBDD slave
  4.         $cat->listarPartidos($db_master); // Ejemplo leyendo de otra BBDD master
  5. } catch (PDOException $pe) {
  6.         echo $pe->getMessage();
  7. }

queda distinto, entonces es una pena...
  #51 (permalink)  
Antiguo 02/09/2010, 22:28
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Si te fijas es el mismo error, mi comentario a manejar el try/catch en donde implementas es para que tu puedas controlar el flujo de tu código, si no se va aparar en el primer exit() y de nada sirve la excepción como tal.

Ahora para que "repares" el error tienes que poner el nombre de la base de datos correcta, por eso te lanza la excepcion.
  #52 (permalink)  
Antiguo 02/09/2010, 23:47
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Si te fijas es el mismo error, mi comentario a manejar el try/catch en donde implementas es para que tu puedas controlar el flujo de tu código, si no se va aparar en el primer exit() y de nada sirve la excepción como tal.

Ahora para que "repares" el error tienes que poner el nombre de la base de datos correcta, por eso te lanza la excepcion.
Jejeje no nos entendiamos, para que el try y catch me mostrase el mismo error que si lo ponia dentro de la clase MyPDO, debía ponerlo no cuando creaba la Categoria sino antes, justo cuando hago la creación de la instancia de la base de datos.

Aquí

Código PHP:
Ver original
  1. try {
  2.     $db_slave = new MyPDO($config_slave);
  3.     $db_slave->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);
  4. } catch(PDOException $e){
  5.     echo $e->getMessage();
  6.     echo "Hubo un error";
  7. }

Y ahora sí, el error que produce era el que estaba intentando ver :D
Me refiero que queda mostrado de la misma manera

SQLSTATE[42000] [1049] Unknown database 'code3lab'Hubo un error

Sin embargo, no consigo que el script termine y no siga mirando cuando no se puede crear la instancia si los datos de conexión no son validos.

Ejemplo:

Código PHP:
Ver original
  1. try {
  2.     $db_slave = new MyPDO($config_slave);
  3. } catch(PDOException $e){
  4.     echo $e->getMessage();
  5.     echo "Hubo un error";
  6.     exit;
  7. }
  8. $db_slave->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);

El script muestra el error pero sigue ejecutandose fuera del TRY y CATCH, porque viene el setAttribute que claro, falla pq no se ha creado la instancia. Pero si funcionase el exit, no debería haber llegado al setAttribute no?

SQLSTATE[42000] [1049] Unknown database 'cod3elab'Hubo un error
Fatal error: Call to a member function setAttribute() on a non-object in C:\wamp\www\00-laboratorio_test\secciones\class_categorias\Nueva\ ConectarCon2_BD_version2\ejemplo1.php on line 59


¿La pregunta es... por qué no finaliza el script dentro del CATCH si hay un exit?

Gracias de antemano!
  #53 (permalink)  
Antiguo 03/09/2010, 06:23
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Como te comento nuevamente, no me estas entendiendo tu puedes realizar todo dentro del mismo try para evitar eso precisamente, por ejemplo:
Código PHP:
Ver original
  1. try {
  2. //Cargo los datos del fichero .ini
  3. $config_slave = new Config('params_slave.ini');
  4. $config_master = new Config('params_master.ini');
  5. &#160;
  6. //Creo el objeto de la base de datos
  7. $db_slave = new MyPDO($config_slave);
  8. $db_slave->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);
  9. $db_master = new MyPDO($config_master);
  10. $db_master->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);
  11. &#160;
  12. //Guardo las instancias diferentes con Registry
  13. Registry::save('db_slave', $db_slave);
  14. Registry::save('db_master', $db_master);
  15. &#160;
  16. //Recupero las instancias con Registry
  17. $db_slave=Registry::get('db_slave');
  18. $db_master=Registry::get('db_master');
  19. &#160;
  20. // Creo el primer objeto el cual hace una conexion con la BBDD slave
  21. $cat= new Categoria($db_slave);
  22. $cat->listarCategorias();
  23. $cat->listarCategorias();
  24. &#160;
  25. // Creo el segundo objeto el cual hace una conexion con la BBDD master
  26. $par= new Partidos($db_master);
  27. $par->listarPartidos();
  28. &#160;
  29. // Cuenta el total de consultas que hubieron en cada BBDD
  30. echo "Consultas realizadas en BD Slave: ".$db_slave->getQueryCount()."<br/>";
  31. echo "Consultas realizadas en BD Master: ".$db_master->getQueryCount()."<br/>";
  32.  
  33. } catch (Exception $e) {
  34.          echo "Ocurrio un error";
  35. }

Saludos.
  #54 (permalink)  
Antiguo 03/09/2010, 13:09
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Haciendolo como me decías me salia el mismo error y era pq en la clase MyPDO tenía tb un TRY CATCH, al quitarlo conseguí que funcionase! Yuhu!

Por cierto, una última duda...

Ahora mi clase MyPDO no utiliza ningún patrón singleton como hacia antes, ¿significa que se me pueden duplicar instancias sin que yo lo sepa, o al utilizar el Registry ya se encarga de alguna manera para que no se dupliquen instancias, aunque me temo que el Registry es simplemente para llevar eso un registro de instancias...?

Pongo un ejemplo:

Código PHP:
Ver original
  1. $config_slave = new Config('params_slave.ini');
  2. $db_slave = new MyPDO($config_slave);
  3. $db_slave->setAttribute(MyPDO::ATTR_ERRMODE, MyPDO::ERRMODE_EXCEPTION);
  4. Registry::save('db_slave', $db_slave);
  5. $db_slave=Registry::get('db_slave');

Hasta aquí sería el proceso inicial que tengo que hacer para hacer toda la conexión... ¿no sé si se podría simplificar en una sola linea... en lugar de tener que poner siempre las 5, quizás una función?

Luego hago uso de las clases que tenga en mi aplicación, las cuales hacen uso de la conexión a la bbdd, para ello les tengo que pasar en todas las clases la instancia de la conexión como parámetro, correcto?

$cat= new Categoria($db_slave);
$cat->listarCategorias();

¿Existe alguna manera de duplicar conexiones de forma "errónea" o todo está creado de tal manera que si se intenta cargar otro conexión con los mismos parámetros que una que esté en uso, no se creará? me refiero a que si todo esta bien para utilizar la clase sin temor a tener instancias de bases de datos por ahí... (vamos lo que bien evita el singleton y que ya no implementa en la clase MyPDO...)

Muchas gracias de antemano!
  #55 (permalink)  
Antiguo 03/09/2010, 16:21
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Duda con PDO y mi clase

Por si solas no se pueden duplicar, es imposible, más bien tu vía código tienes que controlar eso, ¿como? usando el registro siempre, esa es tu tarea de programador.

Ahora resumir todo eso en una sola línea? Pues puedes hacer otra clase que pasandole el parámetro del config cree el objeto y te regrese los datos, esa es precisamente la tarea del patrón Factory.

De hecho ahora pensando podrías usar un patrón Factory con un cache interno y así omites tu Registry (o lo usas internamente), por ejemplo:
Código PHP:
Ver original
  1. class dbFactory
  2. {
  3.          public static function create($sIniFile) {
  4.                   if (Registry::exists($sIniFile)) {
  5.                           return Registry::get($sIniFile);
  6.                   }
  7.  
  8.                   $Config = new Config($sIniFile);
  9.                   $db = new db($Config);
  10.                   Registry::set($sIniFile, $db);
  11.                  
  12.                   return $db;
  13.          }
  14. }
  15.  
  16. $db_master = dbFactory::create('master.ini');
  17. $db_slave = dbFactory::create('slave.ini');

Saludos.

Última edición por GatorV; 03/09/2010 a las 16:27
  #56 (permalink)  
Antiguo 03/09/2010, 16:46
Avatar de neodani  
Fecha de Ingreso: marzo-2007
Mensajes: 1.811
Antigüedad: 17 años, 1 mes
Puntos: 20
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Por si solas no se pueden duplicar, es imposible, más bien tu vía código tienes que controlar eso, ¿como? usando el registro siempre, esa es tu tarea de programador.

Ahora resumir todo eso en una sola línea? Pues puedes hacer otra clase que pasandole el parámetro del config cree el objeto y te regrese los datos, esa es precisamente la tarea del patrón Factory.
Será por patrones! madre mia! xDDDDDDDDDDDDDDDDD

Este es el código final del ejemplo. Funciona perfecto.

Código PHP:
Ver original
  1. <?php
  2. require('config_reader.php');
  3. require('MyPDO.class.php');
  4. require('registry.php');
  5.  
  6. /************************************************************************/
  7. class dbFactory
  8. {
  9.     public static function create($sIniFile) {
  10.         if (Registry::exists($sIniFile)) {
  11.             return Registry::get($sIniFile);
  12.         }
  13.  
  14.         $Config = new Config($sIniFile);
  15.         $db = new MyPDO($Config);
  16.         Registry::save($sIniFile, $db);
  17.  
  18.         return $db;
  19.     }
  20. }
  21. /************************************************************************/
  22. class Categoria{
  23.     private $_con;
  24.    
  25.     public function __construct($DbConexion){
  26.             $this->_con=$DbConexion;
  27.     }
  28.    
  29.     // Listar todas las categorias de la base de datos
  30.     public function listarCategorias(){
  31.         $query = "SELECT nombre FROM categorias";
  32.         $comando = $this->_con->prepare($query);
  33.         $comando->execute();
  34.  
  35.         while( $datos = $comando->fetch() ) {
  36.             echo $datos[0].'<br />';
  37.         }
  38.     }
  39. }
  40. /************************************************************************/
  41. class Partidos{
  42.     private $_con;
  43.    
  44.     public function __construct($DbConexion){
  45.         $this->_con=$DbConexion;
  46.     }
  47.    
  48.     // Listar todos las partidos de la base de datos
  49.     public function listarPartidos(){
  50.         $query = "SELECT home FROM partidos";
  51.         $comando = $this->_con->prepare($query);
  52.         $comando->execute();
  53.  
  54.         while( $datos = $comando->fetch() ) {
  55.         echo $datos[0].'<br />';
  56.         }
  57.     }
  58. }
  59. /************************************************************************/
  60. try {
  61.     $db_master = dbFactory::create('bd_master.ini');
  62.     $db_slave = dbFactory::create('bd_slave.ini');
  63.  
  64.     $cat= new Categoria($db_slave);
  65.     $cat->listarCategorias(); // Leo de la BBDD slave
  66.     $cat->listarCategorias(); // Vuelvo a leer de la BBDD slave
  67.  
  68.     // Creo el segundo objeto el cual hace una conexion con la BBDD master
  69.     $par= new Partidos($db_master);
  70.     $par->listarPartidos(); //Leo de la BBDD
  71.  
  72.     // Cuenta el total de consultas que hubieron en cada BBDD
  73.     echo "Consultas realizadas en BD Slave: ".$db_slave->getQueryCount()."<br/>";
  74.     echo "Consultas realizadas en BD Master: ".$db_master->getQueryCount()."<br/>";
  75.    
  76. } catch (Exception $e) {
  77.     echo $e->getMessage();
  78.     echo "<br/>Ocurrio un error";
  79.     exit;
  80. }
  81. ?>

Saludos y mil gracias por las lecciones del hilo
  #57 (permalink)  
Antiguo 05/09/2010, 03:37
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda con PDO y mi clase

Bueno y para los que desconocen sobre este patrón o desean investigar:

http://desarrolladorsenior.blogspot....y-en-php5.html
  #58 (permalink)  
Antiguo 05/09/2010, 09:35
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por GatorV Ver Mensaje
Porque no mejor heredas tu clase Db de la clase de PDO y te quitas así los problemas de usar return ya que a la hora de en tu constructor regresar otro objeto no se puede.

Saludos.

Si te retorna la instancia PDO dentro del constructor de la clase, pero como un atributo privado.

Código PHP:
Ver original
  1. require('config_reader.php');
  2. require('db.php');
  3. require('registry.php');
  4.  
  5. $config = new Config('params.ini');
  6.  
  7. $db_slave = new db($config);
  8. echo '<pre>'; var_dump($db_slave); echo '</pre>'; exit();

Esto imprimiría:

Connected to database

Código PHP:
Ver original
  1. object(db)#2 (5) {
  2.  ["_username":"db":private]=>
  3.   string(4) "root"
  4.   ["_password":"db":private]=>
  5.   string(12) "jupiter"
  6.   ["_host":"db":private]=>
  7.   string(9) "localhost"
  8.   ["_db":"db":private]=>
  9.   string(6) "codelab"
  10.   ["_conexion":"db":private]=>
  11.   object(PDO)#3 (0) {
  12.  }
  13. }

Por lo que tendrías que tener un método publico getConexion por ejemplo que te devuelva la instancia de PDO en vivo y poder utilizar posteriormente todos los métodos de PDO.

Aunque como dice GatorV es mejor heredar de PDO directamente.
  #59 (permalink)  
Antiguo 05/09/2010, 09:42
atrianaster
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda con PDO y mi clase

Cita:
Iniciado por portalmana Ver Mensaje
Cuando hice un cursillo de java nos dieron una lista aditiva de cuando se podría heredar, como una guía de cuando esta bien que se herede y que no se use por el mero hecho de reutilizar código...

+ Cuando está seguro de que cumple la relación ... es un ...
p.ej.: un zafral no es un empleado (le faltan beneficios, no tiene aumentos de sueldo, etc.)

+ Cuando está seguro de que toda la funcionalidad heredada tiene sentido
p.ej.: si “Documento” incluye un método “entregarMercadería” los “Recibos” no podrán heredar de dicha clase

+ Si la superclase es abstracta se heredarán varias subclases diferentes.
p.ej.: si tubieramos una única clase de Mascota y fuera Perro no tendría sentido que se separaran en dos clases diferentes (Mascota – Perro).

+ Cuando el cuadro de clases obtenido tienen funcionalidades diferentes
(respecto a la superclase y entre subclases)
p.ej.: Si todas las especializaciones de Mascota “ladraran”, “hicieranPiruetas”
y se “rascaranLasPulgas”, aunque fueran “Iguanas”, podrían representarse con la
misma clase agregando un atributo “especie”.

o Cuando piensa que tiene una especialización y nadie le dice que no (¡¡¡ buena suerte !!!)

Y un enlace muy bueno de Enrique

Saludos
Excelentes comentarios

Saludos.
  #60 (permalink)  
Antiguo 26/11/2010, 08:23
Avatar de historiasdemaria  
Fecha de Ingreso: septiembre-2010
Ubicación: www
Mensajes: 433
Antigüedad: 13 años, 6 meses
Puntos: 54
Respuesta: Duda con PDO y mi clase

No entiendo por que Singleton no es bueno para la bd?

Y, por que no crear una clase que herede de PDO e implmentear Singleton dentro para "servir" la connexion

?

Etiquetas: clase, pdo
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

SíEste tema le ha gustado a 3 personas




La zona horaria es GMT -6. Ahora son las 10:11.