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

Conexión a BD MySQL y consultas anidadas

Estas en el tema de Conexión a BD MySQL y consultas anidadas en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Saludos, estoy comenzando en la POO de PHP... para empezar estoy creando una clase de conexion a bd la cual es la siguiente: Código PHP: ...
  #1 (permalink)  
Antiguo 02/01/2010, 08:38
 
Fecha de Ingreso: diciembre-2007
Mensajes: 42
Antigüedad: 16 años, 4 meses
Puntos: 0
Conexión a BD MySQL y consultas anidadas

Saludos, estoy comenzando en la POO de PHP... para empezar estoy creando una clase de conexion a bd la cual es la siguiente:

Código PHP:
    class bd_mysql {
        
/* Variables de conexion */
        
private $servidor;
        private 
$usuario_bd;
        private 
$clave_bd;
        private 
$database;
        
        
/* Variable de resultados de la consulta */
        
private $resultado;
        
        
/* Identificador de conexión y consulta */
        
private $conexion_id;
        private 
$consulta_id;
        
        
/* Método constructor */
        
public function __construct(){
            
$this->servidor "localhost";
            
$this->usuario_bd "root";
            
$this->clave_bd "mysql";
            
$this->database "dumpingoo";
        }
        
        
/*Conexion a la bd*/
        
public function conectar(){
            
/* Conectamos al servidor */
            
$this->conexion_id=mysql_connect($this->servidor$this->usuario_bd$this->clave_bd);
                        
            
/* Seleccionamos la base de datos */
            
mysql_select_db($this->database$this->conexion_id);
        }
        
        public function 
consultar($query){
            if(!empty(
$query)){
                
/* Ejecutamos la consulta */
                
$this->consulta_id=mysql_query($query$this->conexion_id);
            }
        }
        
        
/* Almacenamos el resultado de la consulta en un objeto */
        
public function ver_consulta(){
            
$this->resultado=mysql_fetch_object($this->consulta_id"bd_mysql");
            
            return 
$this->resultado;
        }
        
        public function 
ver_resultado(){
            return 
$this->resultado;
        }
        
        
/* Cerramos la conexión con la base de datos */
        
public function cerrar_conexion(){
            
mysql_close($this->conexion_id);
        }
        
        
/* Libera el contenido que se encuentra en el atributo */
        
public function limpiar_consulta(){
            
mysql_free_result($this->consulta_id);
        }
    } 
Ahora bien, quiero hacer una consulta anidada donde imprimo una sección y sus correspondientes categorias, así:

Sección 1
- Categoria 1
- Categoria 2
- Categoria 3
Sección 2
- Categoria 1
- Categoria 2
- Categoria 3
...

Pero utlizando mi clase tendría que crear varias conexiones a la BD lo cual no es correcto

Código PHP:
    include_once("index.class.php");
    
    
$seccion = new bd_mysql;
    
$seccion->conectar();
    
$seccion->consultar("select nombre_seccion, id_seccion from secciones");
    
$seccion->ver_consulta();
    
    
$categoria = new bd_mysql;
    
$categoria->conectar();
    
    
/* Aqui el codigo con la consulta anidada para obtener la categoria de cada sección */ 
Como ven al hacer esto crearía dos conexiones...

Para solucionarlo he leido un poco sobre el patrón singleton pero con este tendría el problema de que se modificaría el valor de la consulta y su respuesta...

Me gustaria que me ayudaran a encontrar una solución optima, ¿tendrá que utilizar herencia para que la clase 'madre' controle la conexión y en las extendidas hacer la consulta?

Bueno espero sus sugerencias... en todo sentido...
  #2 (permalink)  
Antiguo 02/01/2010, 08:57
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Conexión a BD MySQL y consultas anidadas

mi idea es que: siempre debes utilizar la misma conexión a la base de datos, sin importar cuantos objetos utilices... pues, no necesariamente el concepto debe aplicar a toda la clase

tienes ya la idea, usa el patrón singleton para administrar una única conexión...
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 02/01/2010, 10:29
 
Fecha de Ingreso: diciembre-2007
Mensajes: 42
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: Conexión a BD MySQL y consultas anidadas

Gracias por tu respuesta pateketrueke, pero creo que tengo ciertos vacios en mi concepto del patron Singleton y su utilización...

Este es el problema... como puedes ver en el siguiente codigo, utilizo un ciclo do_while que se encarga de mostrar las secciones y dentro de este se ejecuta otro do_while que muestra las categorias dependiendo de la sección a la que pertenece...

Si utilizo el patron singleton la variable resultado cambiaría en cada iteración del do_while secciones (si es que entiendo bien el funcionamiento de singleton)

Cómo puedo hacerlo entonces?

Código PHP:
<?
                
do{
                    
$sec $seccion->ver_resultado();
                
?>
                    <li><span><? echo $sec->nombre_seccion?></span>
                        <ul>
                            <?
                            $categoria
->consultar("select nombre_categoria, id_categoria from categorias where id_seccion='".$sec->id_seccion."'");
                            
$categoria->ver_consulta();
                            
                            do{
                                
$cat $categoria->ver_resultado();
                            
?>
                                <li><a href="categoria.php?ide=<? echo $cat->id_categoria?>" title=""><? echo $cat->nombre_categoria?></a></li>
                            <?
                            
}while($categoria->ver_consulta());
                            
?>
                        </ul>
                    </li>
                    <br />
                <?
                
}while($seccion->ver_consulta());
                
?>
  #4 (permalink)  
Antiguo 02/01/2010, 12:19
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Conexión a BD MySQL y consultas anidadas

lo único que digo, es que puedes utilizar el patrón singleton solo en la conexión inicial a la base de datos, esto, justo como necesitas: usar varios objetos sin crear conexiones nuevas

Código PHP:
function MiClase extends ObjetoBD {
  function 
__construct()
  {
    
$this->link ConexionBD::get_instance();
  }

obviamente cada objeto puede tener su propio puntero a los resultados, es completamente lógico... pero como no es necesario conectar y desconectar se puede resumir así...

solo hay que conectar una ves a través de nuestras consultas, por muchas que estas sean... y tampoco es necesario cerrar la conexión manualmente, si no, no tiene caso lo anterior
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #5 (permalink)  
Antiguo 07/01/2010, 18:18
 
Fecha de Ingreso: diciembre-2007
Mensajes: 42
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: Conexión a BD MySQL y consultas anidadas

Salidos, realicé unos cambios y creo que el patron singleton ya está funcionando...

Ahora bien, cuando voy a imprimir la seccion y sus categorias... solo muestra la primera sección con sus categorias pero no muestra más resultados...

Código PHP:
    class bd_mysql {
        
/* Variables de conexion */
        
private $servidor;
        private 
$usuario_bd;
        private 
$clave_bd;
        private 
$database;
        
        private static 
$instance;
        
        
/* Identificador de conexión y consulta */
        
private $conexion_id;
        private 
$consulta_id;
        
        
/* Método constructor */
        
private function __construct(){
            
$this->servidor "localhost";
            
$this->usuario_bd "root";
            
$this->clave_bd "mysql";
            
$this->database "dumpingoo";
            
$this->conectar();
        }
        
        public static function 
singleton(){
            if (!isset(
self::$instance)) {
                
$c __CLASS__;
                
self::$instance = new $c;
            }
            return 
self::$instance;
        }

        
/* Clone no permitido */
        
public function __clone(){
            
trigger_error('Clone no se permite.'E_USER_ERROR);
        }

        
/*Conexion a la bd*/
        
public function conectar(){
            
/* Conectamos al servidor */
            
$this->conexion_id=mysql_connect($this->servidor$this->usuario_bd$this->clave_bd);
                        
            
/* Seleccionamos la base de datos */
            
mysql_select_db($this->database$this->conexion_id);
        }
        
        public function 
consultar($query){
            if(!empty(
$query)){
                
/* Ejecutamos la consulta */
                
$this->consulta_id=mysql_query($query$this->conexion_id);
            }
        }
        
        
/* Almacenamos el resultado de la consulta en un objeto */
        
public function ver_consulta(){
            return 
mysql_fetch_object($this->consulta_id"bd_mysql");
        }
    } 
Para imprimir las secciones y sus categorias utilizo un ciclo do_while anidado...

Código PHP:
<?
                
do{
                
?>
                    <li><span><? echo $sec->nombre_seccion?></span>
                        <ul>
                            <?
                            $categoria
->consultar("select nombre_categoria, id_categoria from categorias where id_seccion='".$sec->id_seccion."'");
                            
$cat $categoria->ver_consulta();
                            
                            do{
                            
?>
                                <li><a href="categoria.php?ide=<? echo $cat->id_categoria?>" title=""><? echo $cat->nombre_categoria?></a></li>
                            <?
                            
}while($cat $categoria->ver_consulta());
                            
?>
                        </ul>
                    </li>
                    <br />
                <?
                
}while($sec $seccion->ver_consulta());
                
?>
Espero nuevas luces en este sentido... muchas gracias por su tiempo...
  #6 (permalink)  
Antiguo 12/01/2010, 12:33
Avatar de atoBeto  
Fecha de Ingreso: abril-2008
Ubicación: B.C.S., México
Mensajes: 35
Antigüedad: 16 años
Puntos: 2
Respuesta: Conexión a BD MySQL y consultas anidadas

Una observación, en el código del método ver_consulta() le estás pasando un segundo parámetro a la función mysql_fetch_object que es innecesario:

Código PHP:
       /* Almacenamos el resultado de la consulta en un objeto */
        
public function ver_consulta(){
            return 
mysql_fetch_object($this->consulta_id"bd_mysql");
        } 
Por otro lado la razón por la que veo que el código solo funciona una vez es porque por alguna razón estás utilizando un solo identificador de resultado de consultas, ya que al ejecutar la parte de:

Código PHP:
$cat $categoria->ver_consulta(); 
Se está perdiendo el resultado de la demás secciones y por eso es que ya no continua extrayéndolas.

¿Podrías mostrar el código donde instancias las clases para crear los objetos $seccion y $categoria?

Saludos.
  #7 (permalink)  
Antiguo 12/01/2010, 22:23
 
Fecha de Ingreso: diciembre-2007
Mensajes: 42
Antigüedad: 16 años, 4 meses
Puntos: 0
Respuesta: Conexión a BD MySQL y consultas anidadas

Gracias por la respuesta, pero afortunadamente ya solucioné el problema.

La cuestión es que al utilizar el patrón singleton creo una sola conexión lo cual provocaba que en la iteración anidada de consulta se reemplace el identificador de la consulta (id_consulta).

Para solucionarlo simplemente dejé de utilizar la iteración anidada cambiandola por una consulta "Join", de esta manera el identificador de consulta (id_consulta) no era cambiado en el recorrido del ciclo.

Para quien le pueda interesar aquí les dejo el codigo de la clase y menu...

index.class.php
Código PHP:
class bd_mysql {
        
/* Variables de conexion */
        
private $servidor;
        private 
$usuario_bd;
        private 
$clave_bd;
        private 
$database;
        
        private static 
$instance;
        
        
/* Identificador de conexión y consulta */
        
private $conexion_id;
        private 
$consulta_id;
        
        
/* Método constructor */
        
private function __construct(){
            
$this->servidor "localhost";
            
$this->usuario_bd "root";
            
$this->clave_bd "mysql";
            
$this->database "dumpingoo";
            
$this->conectar();
        }
        
        public static function 
singleton(){
            if (!isset(
self::$instance)) {
                
$c __CLASS__;
                
self::$instance = new $c;
            }
            return 
self::$instance;
        }

        
/* Clone no permitido */
        
public function __clone(){
            
trigger_error('Clone no se permite.'E_USER_ERROR);
        }

        
/*Conexion a la bd*/
        
public function conectar(){
            
/* Conectamos al servidor */
            
$this->conexion_id=mysql_connect($this->servidor$this->usuario_bd$this->clave_bd);
                        
            
/* Seleccionamos la base de datos */
            
mysql_select_db($this->database$this->conexion_id);
        }
        
        public function 
consultar($query){
            if(!empty(
$query)){
                
/* Ejecutamos la consulta */
                
$this->consulta_id=mysql_query($query$this->conexion_id);
            }
        }
        
        
/* Almacenamos el resultado de la consulta en un objeto */
        
public function ver_consulta(){
            return 
mysql_fetch_object($this->consulta_id);
        }
    } 

index.php
Código PHP:
....
....
include_once("index.class.php");
    
    $seccion = bd_mysql::singleton();
    $seccion->consultar("SELECT secciones.*, categorias.* FROM secciones, categorias WHERE secciones.id_seccion = categorias.id_seccion");
    $sec = $seccion->ver_consulta();
    
    do{
        $matriz[$sec->nombre_seccion][$sec->nombre_categoria] = $sec->id_categoria;
    }while($sec = $seccion->ver_consulta());

....
....

<div id="menu1">
            <ul>
                <?
                
foreach($matriz as $seccion => $vseccion){
                
?>
                    <li><span><? echo $seccion?></span>
                        <ul>
                       <?
                        
foreach($vseccion as $categoria => $vcategoria){
                    
?>
                            <li><a href="<? echo $vcategoria?>" ><? echo $categoria?></a></li>
                       <?
                        
}
                    
?>
                        </ul>
                    </li>
                    <br />
                <?
                
}
                
?>
                    <li><div style="text-align: center;">
                        <!-- start *****macro.com code -->
                        <a href="http://www.*****macro.com/index.php?*****macropasto" target="_blank"><b><img src="http://www.*****macro.com/images/banners/es/004.gif" title="***** Macro" alt="***** Macro" border="0" /></b></a>
                        <!-- end *****macro.com code --></div>
                    </li><br />
            </ul>
        </div>
....
....
Y listo... quedo abierto a cualquier sugerencia...
  #8 (permalink)  
Antiguo 25/01/2010, 13:52
 
Fecha de Ingreso: enero-2009
Mensajes: 455
Antigüedad: 15 años, 3 meses
Puntos: 11
Respuesta: Conexión a BD MySQL y consultas anidadas

muy buen post, me permitire copiar tu clase y probar de manera local por aca, gracias y un saludo!
  #9 (permalink)  
Antiguo 10/11/2010, 11:24
 
Fecha de Ingreso: noviembre-2010
Mensajes: 1
Antigüedad: 13 años, 5 meses
Puntos: 0
Respuesta: Conexión a BD MySQL y consultas anidadas

La solución no es agrupar el resultado de una query con join, porque si tubieras que hacer obligatoriamente whiles anidados?? o tienes tantos registros que no es óptimo realizar la join..... Todavía tampoco se muy bien como se resolvería tú problema, pero lo investigaré porque estoy interesado en ello.

Etiquetas: anidadas, bd, mysql
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 1 personas




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