Ver Mensaje Individual
  #15 (permalink)  
Antiguo 10/07/2014, 18:28
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años
Puntos: 320
Respuesta: Menus de ilimitados subniveles

Supongamos la tabla "menus" con los siguientes campos:
menu___id (INT PRIMARY KEY) | menu_name (STRING) | menu_owner (INT FOREIGN KEY menus.menu___id)

Supongamos que se quiere usar PDO.
Supongamos que se esta usando PHP 5 >= 5.3.

Supongamos, que los items del menu raiz, los que no son alojados en ningun otro menu, tienen el campo menu_owner con valor NULL o 0.

Supongamos que la cantidad de elementos de cada menu es ilimitada.
Supongamos que la cantidad de menus es ilimitada.

Suponiendo el escenario anterior, el siguiente codigo puede servir para armar la estructura del menu arbol:
Código PHP:
Ver original
  1. <?php
  2.     $conn = new PDO('mysql:host='.$db['host'].';dbname='.$db['name'], $db['user'],$db['pass']);
  3.     $menu = $conn->prepare("SELECT menu___id, menu_name, IFNULL(menu_owner, 0) FROM menus ORDER BY menu_owner ASC");
  4.     $menu->execute();
  5.  
  6.     $anfitriones = [];
  7.     while($row = $menu->fetch(PDO::FETCH_ASSOC))
  8.     {
  9.         if(!isset($anfitriones[$row["menu_owner"]]))
  10.             $anfitriones[$row["menu_owner"]] = [];
  11.         $anfitriones[$row["menu_owner"]][$row['menu___id']] = [
  12.                                                                  "nombre" => $row['menu_name']
  13.                                                                , "alojados" => []
  14.                                                               ];
  15.     }
  16.  
  17.     foreach($anfitriones[0] as $id_anfitrion => &$referencia)
  18.        $new_referencias[$id_anfitrion] = &$referencia;
  19.  
  20.     $referencias = [];
  21.     while(count($anfitriones) > 1)
  22.     {
  23.         foreach($new_referencias as $id_anfitrion => &$referencia)
  24.             $referencias[$id_anfitrion] = &$referencia;
  25.  
  26.         $new_referencias = [];
  27.         foreach($referencias as $id_anfitrion => &$alojado)
  28.         {
  29.             if(isset($anfitriones[$id_anfitrion]))
  30.             {
  31.                 $alojado["alojados"] = $anfitriones[$id_anfitrion];
  32.                 foreach($alojado["alojados"] as $id_subalojado => &$datos_subalojado)
  33.                     $new_referencias[$id_subalojado] = &$datos_subalojado;
  34.                 unset($anfitriones[$id_anfitrion], $referencias[$id_anfitrion]);
  35.             }
  36.         }
  37.         $referencias = [];
  38.     }
  39.  
  40.     var_dump($anfitriones);

Notece que consume tanta memoria como elementos halla en el menu, por lo que si bien, en teoria el algoritmo funciona con una cantidad ilimitada de elementos, en la practica solo funciona con tantos como entren en la memoria del servidor en simultaneo.
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios

Última edición por NSD; 10/07/2014 a las 18:34