Foros del Web » Programando para Internet » PHP »

Mostrar categorias con funcion recursiva

Estas en el tema de Mostrar categorias con funcion recursiva en el foro de PHP en Foros del Web. Hola a todos! Ando liado con un script y creo que necesito una ayuda, les cuento. Tengo la siguiente tabla ------------------------------- categoria ------------------------------- id categoria_id ...
  #1 (permalink)  
Antiguo 27/07/2011, 02:35
Avatar de bet7o  
Fecha de Ingreso: febrero-2010
Ubicación: DF
Mensajes: 315
Antigüedad: 14 años, 10 meses
Puntos: 20
Mostrar categorias con funcion recursiva

Hola a todos!

Ando liado con un script y creo que necesito una ayuda, les cuento.

Tengo la siguiente tabla

-------------------------------
categoria
-------------------------------
id
categoria_id
nombre
descripcion
-------------------------------

Con esta tabla necesito mostrar las categorías en un elemento select de la siguiente forma

categoria_padre_1
categoria_padre_1 > hija_1
categoria_padre_1 > hija_1 > hija_2
categoria_padre_2
categoria_padre_2 > hija_1
categoria_padre_2 > hija_1 > hija_2
categoria_padre_2 > hija_1 > hija_2 > hija_3

Eh estado intentando pero no doy, alguien podria echarme una mano.

Gracias!
__________________
Pero el no contaba con una cosa, mi peligroso desinteres por la vida humana
  #2 (permalink)  
Antiguo 27/07/2011, 02:44
Avatar de Uncontroled_Duck
Colaborador
 
Fecha de Ingreso: mayo-2011
Ubicación: Málaga [Spain]
Mensajes: 806
Antigüedad: 13 años, 7 meses
Puntos: 261
Respuesta: Mostrar categorias con funcion recursiva

Esto es más de SQl que de php.

Quizás te interese, para tener más claro la estructura crear dos tablas, categorías y subcategorias.

Así podrás enlazar un id_categoria, con los id_subcategoria que quieras.
Quedaría así mas o menos
Código:
cat | sub
 1  -  1
 1  -  2
 2  -  1
 2  -  2
 2  -  3
__________________
Todos agradeceremos que pongas el código en su respectivo Highlight
  #3 (permalink)  
Antiguo 27/07/2011, 03:08
Avatar de bet7o  
Fecha de Ingreso: febrero-2010
Ubicación: DF
Mensajes: 315
Antigüedad: 14 años, 10 meses
Puntos: 20
Respuesta: Mostrar categorias con funcion recursiva

Uncontroled_Duck ya logro sacar el formato que necesito, el unico problema es que los indices con categorias padres no me los respeta.

El script me quedo así

Código PHP:
Ver original
  1. public function getPath($parent = NULL, $child = 0, $nombre = NULL)
  2.  
  3.   {
  4.  
  5.     $conditions = $child == 0 ? 'categoria_id IS NULL' : "categoria_id = $parent";
  6.  
  7.     /* Categorias padres */
  8.  
  9.     $rs = $this->find("conditions: $conditions");
  10.  
  11.     if(!$rs) return array();
  12.  
  13.     $path = array();
  14.  
  15.     /* Iteraccion de categorias padres */
  16.  
  17.     foreach($rs as $item)
  18.  
  19.     {
  20.  
  21.       $path[$item->id] = Validate::isNull($nombre) ? $item->nombre : "$nombre > $item->nombre";
  22.  
  23.       /* Iteraccion de categorias hijas */
  24.  
  25.       $childs = $this->getPath($item->id, 1, $path[$item->id]);
  26.  
  27.       if(count($childs) > 0)
  28.  
  29.         $path = array_merge($path, $childs);
  30.  
  31.     }
  32.  
  33.     return $path;
  34.  
  35.   }

y el resultado que me arroja es

Código PHP:
Ver original
  1. (
  2.     [0] => Switches
  3.     [1] => Switches > Routers
  4.     [2] => Switches > Routers > Storage
  5.     [3] => Switches > Routers > Storage > Gateway, Ata y Accesorios
  6.     [1002] => Tecnología Inalámbrica
  7.     [1003] => Seguridad
  8.     [1005] => Unified Communications
  9. )

como se puede ver, las primeras categorias no tienen el id correcto.

Alguna idea?

Saludos!
__________________
Pero el no contaba con una cosa, mi peligroso desinteres por la vida humana
  #4 (permalink)  
Antiguo 27/07/2011, 04:04
Avatar de bet7o  
Fecha de Ingreso: febrero-2010
Ubicación: DF
Mensajes: 315
Antigüedad: 14 años, 10 meses
Puntos: 20
Respuesta: Mostrar categorias con funcion recursiva

Al final me quedo en una sola tabla con relacion recursiva, como la tenia y el script es este

Código PHP:
Ver original
  1. public function treeCategory($parent = NULL, $child = 0, $nombre = NULL)
  2.  
  3.   {
  4.  
  5.     $conditions = $child == 0 ? 'categoria_id IS NULL' : "categoria_id = $parent";
  6.  
  7.     /* Categorias padres */
  8.  
  9.     $rs = $this->find("conditions: $conditions");
  10.  
  11.     if(!$rs) return;
  12.  
  13.     $path = array();
  14.  
  15.     /* Iteraccion de categorias padres */
  16.  
  17.     foreach($rs as $item)
  18.  
  19.     {
  20.  
  21.       $path[$item->id] = Validate::isNull($nombre) ? $item->nombre : "$nombre > $item->nombre";
  22.  
  23.       /* Iteraccion de categorias hijas */
  24.  
  25.       $childs = $this->treeCategory($item->id, 1, $path[$item->id]);
  26.  
  27.       if(count($childs) > 0) foreach($childs as $k => $v) $path[$k] = $v;
  28.  
  29.     }
  30.  
  31.     return $path;
  32.  
  33.   }

Yo utilizo un FW pero la idea se puede captar muy bien, si alguien tiene algo mejor estaria muy bien que lo comentara.

Saludos!
__________________
Pero el no contaba con una cosa, mi peligroso desinteres por la vida humana
  #5 (permalink)  
Antiguo 27/07/2011, 04:09
Avatar de Eleazan  
Fecha de Ingreso: abril-2008
Ubicación: Ibiza
Mensajes: 1.879
Antigüedad: 16 años, 8 meses
Puntos: 326
Respuesta: Mostrar categorias con funcion recursiva

No sé, yo habría usado una tabla tipo

id | categoria | nombre | descripcion | categoria_padre

Y en categoria padre el id de la categoria padre. En caso de no tener, sería 0.

Después, es más sencillo construir el "tree" :)
  #6 (permalink)  
Antiguo 27/07/2011, 04:14
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 9 meses
Puntos: 253
Respuesta: Mostrar categorias con funcion recursiva

Cita:
Iniciado por Eleazan Ver Mensaje
No sé, yo habría usado una tabla tipo

id | categoria | nombre | descripcion | categoria_padre

Y en categoria padre el id de la categoria padre. En caso de no tener, sería 0.

Después, es más sencillo construir el "tree" :)
Una autorelación, clave foranea referenciando a clave primaria de la misma tabla. Coincido con @Eleazan que sería lo suyo para este caso.

Un saludo y suerte.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #7 (permalink)  
Antiguo 27/07/2011, 04:16
Avatar de Eleazan  
Fecha de Ingreso: abril-2008
Ubicación: Ibiza
Mensajes: 1.879
Antigüedad: 16 años, 8 meses
Puntos: 326
Respuesta: Mostrar categorias con funcion recursiva

Cita:
Iniciado por vgonga1986 Ver Mensaje
Una autorelación, clave foranea referenciando a clave primaria de la misma tabla. Coincido con @Eleazan que sería lo suyo para este caso.

Un saludo y suerte.
Cambia la r de "autorelacion" por otra letra... por ejemplo, una f......

Ná, es broma xD

Hace mucho que estudié BBDD, nunca me acuerdo de los nombres... sólo sé que me salia todo pq era "lógico" :)
  #8 (permalink)  
Antiguo 27/07/2011, 04:26
Avatar de Uncontroled_Duck
Colaborador
 
Fecha de Ingreso: mayo-2011
Ubicación: Málaga [Spain]
Mensajes: 806
Antigüedad: 13 años, 7 meses
Puntos: 261
Respuesta: Mostrar categorias con funcion recursiva

Es otra opción totalmente viable, tengo costumbre de separar datos por el tema del orden, y por si hay que realizar cambios o ampliar las tablas, me resulta más sencillo hacerlo de esa forma. Pero vamos, que el lo importante es el resultado, si algo tiene esto, es que se puede obtener lo mismo de distintas formas

Un saludo,
__________________
Todos agradeceremos que pongas el código en su respectivo Highlight
  #9 (permalink)  
Antiguo 27/07/2011, 04:31
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 9 meses
Puntos: 253
Respuesta: Mostrar categorias con funcion recursiva

Pero una categoría y una subcategoría al fin son categorías, luego tiene sentido que en la base de datos sean la misma entidad. Es la primera regla de los modelos de Entidad-Relación, si algo se parece mucho entre si mételo en la misma Entidad y si tienes algo que se diferencia mucho, sepáralo en dos Entidades. En este caso, estamos en el primer caso, misma Entidad. Pero vamos, funcionar funciona todo, es tema de diseño y ya estamos en terreno pantanoso por su propia subjetividad, jeje.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #10 (permalink)  
Antiguo 27/07/2011, 04:51
Avatar de bet7o  
Fecha de Ingreso: febrero-2010
Ubicación: DF
Mensajes: 315
Antigüedad: 14 años, 10 meses
Puntos: 20
De acuerdo Respuesta: Mostrar categorias con funcion recursiva

Cita:
Iniciado por vgonga1986 Ver Mensaje
Una autorelación, clave foranea referenciando a clave primaria de la misma tabla. Coincido con @Eleazan que sería lo suyo para este caso.

Un saludo y suerte.
De echo mi tabla es así como dicen, con una relación recursiva, pero no puedo ponerle 0 a las categorías padres porque las asociaciones no me lo permiten.

La categoria 0 no existe.

-------------------------------
categoria
-------------------------------
id
categoria_id
nombre
descripcion
-------------------------------

Ahora el codigo final es este.

Código PHP:
Ver original
  1. /**
  2.  
  3.    * Obtiene un arreglo con las categorias y su respectivo path.
  4.  
  5.    *
  6.  
  7.    *   Ej. categoria_1 > subcategoria_1 > subcategoria_1.1
  8.  
  9.    *
  10.  
  11.    * @param id $parent Id de la categoria padre.
  12.  
  13.    * @param string $nombre Nombre del path para la categoria hija.
  14.  
  15.    * @param string $blank Texto a mostrar en el primer option, si es nulo no genera el indice
  16.  
  17.    * @return array
  18.  
  19.    */
  20.  
  21.   public function treeCategory($parent = NULL, $nombre = NULL, $blank = NULL)
  22.  
  23.   {
  24.  
  25.     $conditions = Validate::isNull($parent) ? 'categoria_id IS NULL' : "categoria_id = $parent";
  26.  
  27.     $rs = $this->find("conditions: $conditions");
  28.  
  29.     if(!$rs) return;
  30.  
  31.     $path = array();
  32.  
  33.     if(!Validate::isNull($blank)) $path[''] = $blank;
  34.  
  35.     foreach($rs as $item)
  36.  
  37.     {
  38.  
  39.       $path[$item->id] = Validate::isNull($nombre) ? $item->nombre : "$nombre > $item->nombre";
  40.  
  41.       $childs = $this->treeCategory($item->id, $path[$item->id]);
  42.  
  43.       if(count($childs) > 0) foreach($childs as $k => $v) $path[$k] = $v;
  44.  
  45.     }
  46.  
  47.     return $path;
  48.  
  49.   }

Comparto tu opinion Uncontroled_Duck una categoría y una subcategoría al fin son categorías

Saludos!
__________________
Pero el no contaba con una cosa, mi peligroso desinteres por la vida humana
  #11 (permalink)  
Antiguo 27/07/2011, 05:01
Avatar de Eleazan  
Fecha de Ingreso: abril-2008
Ubicación: Ibiza
Mensajes: 1.879
Antigüedad: 16 años, 8 meses
Puntos: 326
Respuesta: Mostrar categorias con funcion recursiva

¿Y como sabes quien es el padre?
  #12 (permalink)  
Antiguo 27/07/2011, 05:32
Avatar de bet7o  
Fecha de Ingreso: febrero-2010
Ubicación: DF
Mensajes: 315
Antigüedad: 14 años, 10 meses
Puntos: 20
Respuesta: Mostrar categorias con funcion recursiva

PK => id
FK => categoria_id

Saludos!
__________________
Pero el no contaba con una cosa, mi peligroso desinteres por la vida humana
  #13 (permalink)  
Antiguo 27/07/2011, 05:41
Avatar de Eleazan  
Fecha de Ingreso: abril-2008
Ubicación: Ibiza
Mensajes: 1.879
Antigüedad: 16 años, 8 meses
Puntos: 326
Respuesta: Mostrar categorias con funcion recursiva

Perfect :) Me confundia el nombre del campo xD
  #14 (permalink)  
Antiguo 27/07/2011, 07:01
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 11 meses
Puntos: 845
Respuesta: Mostrar categorias con funcion recursiva

Que tal bet7o,

Te dejo una referencia http://www.sitepoint.com/hierarchical-data-database/ y un comentario, el adjacency list model(lo que tu tienes) si bien es lo mas simple lejos esta de ser lo mas eficiente, por lo general es mejor opción el NestedSet, te sugiero que inviertas algo de tiempo en ver las diferentes opciones ya que el manejo de las estructuras de árbol es algo recurrente.

Y si realmente te interesa el tema, este libro lo trata en mas detalle, Joe Celko's Trees and Hierarchies in SQL for Smarties.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)

Última edición por masterpuppet; 27/07/2011 a las 07:19 Razón: typo

Etiquetas: categorias, funcion, recursiva, tabla
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 20:11.