sql >> Base de Datos >  >> RDS >> Mysql

Cómo construir un nivel ilimitado de menú a través de PHP y mysql

Esta es una versión "apta para desarrolladores" de "una consulta , sin recursividad " solución para este problema.

SQL :

SELECT id, parent_id, title, link, position FROM menu_item ORDER BY parent_id, position;

PHP :

$html = '';
$parent = 0;
$parent_stack = array();

// $items contains the results of the SQL query
$children = array();
foreach ( $items as $item )
    $children[$item['parent_id']][] = $item;

while ( ( $option = each( $children[$parent] ) ) || ( $parent > 0 ) )
{
    if ( !empty( $option ) )
    {
        // 1) The item contains children:
        // store current parent in the stack, and update current parent
        if ( !empty( $children[$option['value']['id']] ) )
        {
            $html .= '<li>' . $option['value']['title'] . '</li>';
            $html .= '<ul>'; 
            array_push( $parent_stack, $parent );
            $parent = $option['value']['id'];
        }
        // 2) The item does not contain children
        else
            $html .= '<li>' . $option['value']['title'] . '</li>';
    }
    // 3) Current parent has no more children:
    // jump back to the previous menu level
    else
    {
        $html .= '</ul>';
        $parent = array_pop( $parent_stack );
    }
}

// At this point, the HTML is already built
echo $html;

Solo necesita comprender el uso de la variable $parent_stack.

Es una pila "LIFO" (Last In, First Out) - la imagen en el artículo de Wikipedia vale más que mil palabras:http://en.wikipedia.org/wiki/LIFO_%28computing%29

Cuando una opción de menú tiene subopciones, almacenamos su ID principal en la pila:

array_push( $parent_stack, $parent );

Y luego, actualizamos inmediatamente $parent, convirtiéndolo en el ID de la opción de menú actual:

$parent = $option['value']['id'];

Después de recorrer todas sus subopciones, podemos volver al nivel anterior:

$parent = array_pop( $parent_stack );

¡Es por eso que almacenamos la identificación principal en la pila!

Mi sugerencia es:contempla el fragmento de código anterior y entiéndelo.

¡Las preguntas son bienvenidas!

Una de las ventajas que veo en este enfoque es que elimina el riesgo de entrar en un ciclo infinito, lo que puede suceder cuando se usa la recursividad.