Foros del Web » Programando para Internet » PHP »

Sumar nodos en función recursiva PHP - Menú - Categorías

Estas en el tema de Sumar nodos en función recursiva PHP - Menú - Categorías en el foro de PHP en Foros del Web. Queridísimos amigos. Sigo desarrollando un menú buenísimo, creado inicialmente por el colaborador Triby . El desafío ahora es sumar los hijos de las categorías, agregando ...
  #1 (permalink)  
Antiguo 14/10/2014, 00:07
 
Fecha de Ingreso: abril-2012
Ubicación: Argentina
Mensajes: 215
Antigüedad: 12 años
Puntos: 2
Sumar nodos en función recursiva PHP - Menú - Categorías

Queridísimos amigos. Sigo desarrollando un menú buenísimo, creado inicialmente por el colaborador Triby.

El desafío ahora es sumar los hijos de las categorías, agregando "(número)", por ejemplo, de esta forma:

Código HTML:
Ver original
  1. Categoria_a (5)
  2. Categoria_b (12)
  3. Categoria_c (0)

Código del Menú:
Código PHP:
Ver original
  1. // Cargamos opciones del menú
  2. function cargaMenu($mysqli) {
  3.     $menu = array('todos' => array());
  4.     // Falta una columna que permita seleccionar orden
  5.     // Ahora se muestran como fueron dados de alta
  6.     $sql = "SELECT * FROM productos";
  7.     $res = $mysqli->query($sql);
  8.     while($row = $res->fetch_assoc()) {
  9.         $id_padre = $row['productos_parent_id'];
  10.         // Verificamos si existe el menú padre o lo creamos
  11.         (!isset($menu[$id_padre]) && $menu[$id_padre] = array());
  12.         // Agregamos ID del elemento actual al padre
  13.         $menu[$id_padre][] = $row['productos_id'];
  14.         // Agregamos el elemento actual al arreglo 'todos'
  15.         $menu['todos'][$row['productos_id']] = $row;
  16.     }
  17.     return $menu;
  18. }
  19.  
  20. // Mostramos menú
  21. function menu($id_padre, $hijos, $menu) {
  22.     $html = "<ul>\n";
  23.       foreach($menu[$id_padre] as $id_menu) {  
  24.           $html .= '<li><a href="pagina.php?opcion='.$id_menu.'">'.$menu['todos'][$id_menu]['productos_nombre'].'</a>';
  25.          // Este menú tiene hijos?
  26.          if(isset($menu[$id_menu])) {      
  27.             //Si quiero ver los hijos
  28.             if($hijos=="ver_hijos") {                
  29.               $html .= menu($id_menu, $hijos, $menu );
  30.             }
  31.             //o no verlos  
  32.             if($hijos=="ocultar_hijos "){                  
  33.             }          
  34.          }       
  35.          $html .= "</li>\n";
  36.     }
  37.     $html .= "</ul>\n";
  38.     // Devuelve el valor
  39.     return $html;  
  40. }
  41. // Lo hacemos funcionar
  42. $mysqli = crearConexion();
  43. $menu = cargaMenu($mysqli);
  44.    
  45. // Mostramos menú, padre=0 para menú principal
  46. echo menu(1,  "ocultar_hijos", $menu);

Esto muestra en pantalla:

Código HTML:
Ver original
  1. Categoria_a
  2. Categoria_b
  3. Categoria_c

No sé por donde empezar, creería uso de un arreglo, luego agregarlo a algo como esto:

Código PHP:
             $html .= '<li><a href="pagina.php?opcion='.$id_menu.'">'.$menu['todos'][$id_menu]['productos_nombre'];
             
$html .=" ( aquí número )";
             
$html .='</a>'
  #2 (permalink)  
Antiguo 14/10/2014, 02:48
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

Si puedes listarlos los puedes sumar.... pero no se entiende que pretendes hacer ni para que.

Pretendes saber los elementos que tiene cada categoria?

Código MySQL:
Ver original
  1. SELECT c.idCategoria,c.categoria,
  2.              count(p.idProducto) numProductos
  3. FROM categorias c INNER JOIN productos p
  4.           ON c.idCategoria=p.idCategoria
  5. GROUP BY categoria;
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 14/10/2014 a las 12:07
  #3 (permalink)  
Antiguo 14/10/2014, 08:32
 
Fecha de Ingreso: abril-2012
Ubicación: Argentina
Mensajes: 215
Antigüedad: 12 años
Puntos: 2
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

Hola Quimfv. Gracias por responderme.

Entonces creo una tabla "categorias" para unirla con la de "productos" y ver la cantidad de "categorias" de las mismas que existen, para poder luego sumarlas. ¿Es así?

Aclaro mejor la cuestión
Lo que pretendo es que gracias al código completo del post anterior, enfatizando la línea 24:
Código PHP:
Ver original
  1. $html .= '<li><a href="pagina.php?opcion='.$id_menu.'">'.$menu['todos'][$id_menu]['productos_nombre'].'</a>';

Me tira las categorías según el "id_padre", por ejemplo:
  • En PHP:
    Código PHP:
    Ver original
    1. echo menu(1,  "ocultar_hijos", $menu);
  • En pantalla, aparecen estos links:
    Código HTML:
    Ver original
    1. Categoria_a
    2. Categoria_b
    3. Categoria_c

*Lo único que falta es mostrar, en cada enlace, la cantidad sumada de hijos entre "()".

*La idea es hacer diferentes filtros o consultas hacia el menú mostrando entre "()" los resultados:

Por ejemplo, este sitio: http://celulares.mercadolibre.com.ar...aras-externas/ en la parte izquierda hay un menú con filtros.

¿Debería crear una tabla extra para esto?

Última edición por mikehove; 14/10/2014 a las 09:20
  #4 (permalink)  
Antiguo 14/10/2014, 12:15
 
Fecha de Ingreso: diciembre-2008
Mensajes: 8
Antigüedad: 15 años, 4 meses
Puntos: 1
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

Creo que está mal implementado tu solución.

Primero tendrías que hacer una consulta de todos los menús padres con su correspondiente count(). después ya pintar los hijos. O sólo que haya entendido mal tu planteamiento :p
  #5 (permalink)  
Antiguo 14/10/2014, 12:28
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 15 años, 8 meses
Puntos: 2237
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

Con esa estructura del array es muy fácil contar los hijos:

Código PHP:
Ver original
  1. if(isset($menu[$id_padre])) {
  2.     echo count($menu[$id_padre]);
  3. }
__________________
- León, Guanajuato
- GV-Foto
  #6 (permalink)  
Antiguo 14/10/2014, 12:43
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

No estaria de más que llamases la atención de @Triby si es que es el autor de esto.

No acabo de entender la linea 11, entiendo lo que pretende pero no entiendo su sintaxis.

En mi post anterior queria hacerte notar que quizas era más facil obtener ese numero a partir de una query, pero habria que analizar la estructura de tu bbdd.

En cualquier caso creo que lo que buscas se podria solucionar anlizando el arbol de arrays que parece montar el script, parece que en el array $menu[$id_padre] se guardan todos los productos con el mismo padre luego el numero de elementos de ese array es el numero que buscas para ese padre, no?

Código PHP:
Ver original
  1. $html .= '<li><a href="pagina.php?opcion='.$id_menu.'">'.$menu['todos'][$id_menu]['productos_nombre'];
  2.              $html .=" ( ".count($menu[$id_padre])." )";
  3.              $html .='</a>';

Para verlo claro tendriamos que montar una bbdd que tenga la estructura necesaria para que el script de @Triby funcine, de ahí que te decia que llamases su atención.

Otra opción es que ejecutes lo siguiente en la linea 44 del script y nos muestres el resultado.

Código PHP:
Ver original
  1. echo "<pre>";
  2. print_r($menu);
  3. echo "</pre>";

Tu mismo podrás analizar la estructura del array y ver que count te da el numero que buscas.


Edito: vaya me he estado más de 20 minutos para darte una respuesta razonable y solo tenia que esperar a que @Triby te lo resolviera con toda seguridad. Doy la respuesta y ahí esta @Triby!!! Menos mal que mi intuición era acertada.

En cuanto la linea 11? @Triby?
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #7 (permalink)  
Antiguo 14/10/2014, 15:06
 
Fecha de Ingreso: abril-2012
Ubicación: Argentina
Mensajes: 215
Antigüedad: 12 años
Puntos: 2
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

Primero que todo quiero disculparme con Uds. por el tiempo y algún conflicto que haya generado y darles mis sinceras gracias por responderme.

*Con la guía de Triby (es muy probable que yo lo haya colocado en el lugar incorrecto):
Código PHP:
Ver original
  1. $html .= '<li><a href="pagina.php?opcion='.$id_menu.'">'.$menu['todos'][$id_menu]['productos_nombre'];
  2.     if(isset($menu[$id_padre])) {
  3.           $numero = count($menu[$id_padre]);
  4.           $html .="(".$numero.")";                
  5.     }        
  6. $html .='</a>';
Arroja en pantalla:


*Con tu ayuda Quimfv (también imprime en pantalla el mismo resultado que Triby):
Código PHP:
Ver original
  1. $html .= '<li><a href="pagina.php?opcion='.$id_menu.'">'.$menu['todos'][$id_menu]['productos_nombre'];
  2. $html .=" ( ".count($menu[$id_padre])." )";
  3. $html .='</a>';
Agregando el "print_r":
Código HTML:
Ver original
  1. Array
  2. (
  3.     [todos] => Array
  4.         (
  5.             [1] => Array
  6.                 (
  7.                     [productos_id] => 1
  8.                     [productos_parent_id] => 0
  9.                     [productos_nombre] => Inicio
  10.                 )
  11.  
  12.             [2] => Array
  13.                 (
  14.                     [productos_id] => 2
  15.                     [productos_parent_id] => 1
  16.                     [productos_nombre] => Categoria1
  17.                 )
  18.  
  19.             [3] => Array
  20.                 (
  21.                     [productos_id] => 3
  22.                     [productos_parent_id] => 1
  23.                     [productos_nombre] => Categoria2
  24.                 )
  25.  
  26.             [4] => Array
  27.                 (
  28.                     [productos_id] => 4
  29.                     [productos_parent_id] => 1
  30.                     [productos_nombre] => Categoria3
  31.                 )
  32.  
  33.             [5] => Array
  34.                 (
  35.                     [productos_id] => 5
  36.                     [productos_parent_id] => 2
  37.                     [productos_nombre] => Categoria1_Subcategoria1
  38.                 )
  39.  
  40.             [6] => Array
  41.                 (
  42.                     [productos_id] => 6
  43.                     [productos_parent_id] => 4
  44.                     [productos_nombre] => Categoria3_Subcategoria1
  45.                 )
  46.  
  47.             [7] => Array
  48.                 (
  49.                     [productos_id] => 7
  50.                     [productos_parent_id] => 4
  51.                     [productos_nombre] => Categoria3_Subcategoria2
  52.                 )
  53.  
  54.         )
  55.  
  56.     [0] => Array
  57.         (
  58.             [0] => 1
  59.         )
  60.  
  61.     [1] => Array
  62.         (
  63.             [0] => 2
  64.             [1] => 3
  65.             [2] => 4
  66.         )
  67.  
  68.     [2] => Array
  69.         (
  70.             [0] => 5
  71.         )
  72.  
  73.     [4] => Array
  74.         (
  75.             [0] => 6
  76.             [1] => 7
  77.         )
  78.  
  79. )

Otros datos de la idea:

Página completa con su conexión a la BBDD:
Código PHP:
Ver original
  1. <?php  
  2.     function crearConexion(){
  3.         //Datos para la conexión con el servidor
  4.         $servidor   = "localhost";
  5.         $nombreBD   = "base2";
  6.         $usuario    = "root";
  7.         $contrasena = "";
  8.         //Creando la conexión, nuevo objeto mysqli
  9.         $conexion = new mysqli($servidor,$usuario,$contrasena,$nombreBD);
  10.         //Si sucede algún error la función muere e imprimir el error
  11.         if($conexion->connect_error){
  12.             die("Error en la conexion : ".$conexion->connect_errno.
  13.                                       "-".$conexion->connect_error);
  14.         }
  15.         //Si nada sucede retornamos la conexión
  16.         return $conexion;
  17.     }
  18.        
  19.        // Cargamos opciones del menú
  20. function cargaMenu($mysqli) {
  21.     $menu = array('todos' => array());
  22.     // Falta una columna que permita seleccionar orden
  23.     // Ahora se muestran como fueron dados de alta 
  24.  
  25.     $sql = "SELECT * FROM productos";
  26.     $res = $mysqli->query($sql);
  27.     while($row = $res->fetch_assoc()) {
  28.         $id_padre = $row['productos_parent_id'];
  29.         // Verificamos si existe el menú padre o lo creamos
  30.         (!isset($menu[$id_padre]) && $menu[$id_padre] = array());
  31.         // Agregamos ID del elemento actual al padre
  32.         $menu[$id_padre][] = $row['productos_id'];
  33.         // Agregamos el elemento actual al arreglo 'todos'
  34.         $menu['todos'][$row['productos_id']] = $row;
  35.     }
  36.     return $menu;
  37. }
  38.  
  39. // Mostramos menú
  40. function menu($id_padre, $hijos, $menu) {
  41.     $html = "<ul>\n";
  42.       foreach($menu[$id_padre] as $id_menu) {  
  43.           $html .= '<li><a href="pagina.php?opcion='.$id_menu.'">'.$menu['todos'][$id_menu]['productos_nombre'];
  44.           $html .=" ( ".count($menu[$id_padre])." )";    
  45.           $html .='</a>';
  46.          // Este menú tiene hijos?
  47.          if(isset($menu[$id_menu])) {      
  48.             //Si quiero ver los hijos
  49.             if($hijos=="ver_hijos") {                
  50.               $html .= menu($id_menu, $hijos, $menu );
  51.             }
  52.             //o no verlos  
  53.             if($hijos=="ocultar_hijos "){                  
  54.             }          
  55.          }       
  56.          $html .= "</li>\n";
  57.     }
  58.     $html .= "</ul>\n";
  59.     // Devuelve el valor
  60.     return $html;  
  61. }
  62. // Lo hacemos funcionar
  63. $mysqli = crearConexion();
  64. $menu = cargaMenu($mysqli);
  65.    
  66. // Mostramos menú, padre=0 para menú principal
  67. echo menu(1,  "ver_hijos", $menu);
  68. echo "<pre>";
  69. print_r($menu);
  70. echo "</pre>";
  71.      
  72. ?>

Estructura de la tabla:

Código SQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `productos` (
  2.   `productos_id` INT(11) NOT NULL AUTO_INCREMENT,
  3.   `productos_parent_id` INT(11) NOT NULL,
  4.   `productos_nombre` VARCHAR(30) COLLATE utf8_spanish_ci DEFAULT NULL,
  5.   PRIMARY KEY (`productos_id`)
  6. )
  7. INSERT INTO `productos` (`productos_id`, `productos_parent_id`, `productos_nombre`) VALUES
  8. (1, 0, 'Inicio'),
  9. (2, 1, 'Categoria1'),
  10. (3, 1, 'Categoria2'),
  11. (4, 1, 'Categoria3'),
  12. (5, 2, 'Categoria1_Subcategoria1'),
  13. (6, 4, 'Categoria3_Subcategoria1'),
  14. (7, 4, 'Categoria3_Subcategoria2');

Más gráficamente esta es la idea que muestre la suma de los hijos:



Ojalá me puedan dar otro empujón, amigos! Por favor
  #8 (permalink)  
Antiguo 15/10/2014, 11:14
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 15 años, 8 meses
Puntos: 2237
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

@quimfv, si tu duda se refiere a esto:

Código PHP:
Ver original
  1. (!isset($menu[$id_padre]) && $menu[$id_padre] = array());
  2.  
  3. // Es el equivalente de
  4. if(!isset($menu[$id_padre])) {
  5.      $menu[$id_padre] = array();
  6. }

No recuerdo si tiene algún nombre ese tipo de estructura, pero sí recuerdo haberlas visto en algún framework o CMS y me pareció muy útil para algunos casos.

@mikehove, no sé porqué te complicas tanto con algo tan sencillo:

Código PHP:
Ver original
  1. if(isset($menu[$id_padre])) {
  2.     echo '(' . count($menu[$id_padre]) . ')';
  3. } else {
  4.     echo '(0)';
  5. }
__________________
- León, Guanajuato
- GV-Foto

Última edición por Triby; 16/10/2014 a las 01:02 Razón: Era "count()" y no el elemento del array! :borracho:
  #9 (permalink)  
Antiguo 16/10/2014, 00:49
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

Gracias @Triby es lo que intuia, pero no la habia visto nunca, si que es simple.... pero clara a medias... no?
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #10 (permalink)  
Antiguo 16/10/2014, 01:00
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 15 años, 8 meses
Puntos: 2237
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

@quimfv, una vez que te acostumbras la ves muy simple, reconozco que originalmente pensé "Qué fea forma de programar, es de flojos", pero me gustó cuando la comencé a usar.

El único problema es que algunos editores pueden marcar esa línea como error y hay que usar and / or en lugar de && / ||; es el caso de PhpStorm.
__________________
- León, Guanajuato
- GV-Foto
  #11 (permalink)  
Antiguo 21/10/2014, 21:24
 
Fecha de Ingreso: abril-2012
Ubicación: Argentina
Mensajes: 215
Antigüedad: 12 años
Puntos: 2
Respuesta: Sumar nodos en función recursiva PHP - Menú - Categorías

Perdón la tardanza... Tuve algunos problemas personales pero ya está, quiero seguir adelante con este tema para llegar al éxito.

Gracias por contestarme amigo Triby, quisiera no complicarme y hay cosas que para mí no son tan sencillas.

Comento:

-Dejé la bendita línea 11 tal cual:
Código PHP:
Ver original
  1. (!isset($menu[$id_padre]) && $menu[$id_padre] = array());

-Comparando con tu anterior post, dejé modificado las líneas 5 a la 9:
Código PHP:
Ver original
  1. function menu($id_padre, $hijos, $menu) {
  2.     $html = "<ul>\n";
  3.          foreach($menu[$id_padre] as $id_menu) {  
  4.          $html .= '<li><a href="pagina.php?opcion='.$id_menu.'">'.$menu['todos']               [$id_menu]['productos_nombre'];
  5.               if(isset($menu[$id_padre])) {
  6.               $html .=" ( ".count($menu[$id_padre])." )";  
  7.               }else {
  8.                   $html .=" (0) ";
  9.               }          
  10.          $html .='</a>';
  11.          // Este menú tiene hijos?
  12.          if(isset($menu[$id_menu])) {      
  13.             //Si quiero ver los hijos
  14.             if($hijos=="ver_hijos") {                
  15.               $html .= menu($id_menu, $hijos, $menu );
  16.             }
  17.             //o no verlos  
  18.             if($hijos=="ocultar_hijos "){                  
  19.             }          
  20.          }      
  21.          $html .= "</li>\n";
  22.     }
  23.     $html .= "</ul>\n";
  24.     // Devuelve el valor
  25.     return $html;  
  26. }

Me sigue dando el mismo resultado defectuoso:


No se por qué no independiza el conteo de hijos de cada categoría, de esta forma:


¿Dónde estará el loco error?

Etiquetas: php+arrays
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 14:47.