sql >> Database teknologi >  >> RDS >> Mysql

Sådan bygger du ubegrænset menuniveau gennem PHP og mysql

Her er en "udviklervenlig" version af "én forespørgsel , ingen rekursion " løsning på dette problem.

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;

Du skal bare forstå brugen af ​​$parent_stack-variablen.

Det er en "LIFO"-stak (Last In, First Out) - billedet i Wikipedia-artiklen er mere end tusind ord værd:http://en.wikipedia.org/wiki/LIFO_%28computing%29

Når et menupunkt har undervalg, gemmer vi dets forældre-id i stakken:

array_push( $parent_stack, $parent );

Og så opdaterer vi straks $parent, hvilket gør det til det aktuelle menuvalg ID:

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

Efter at vi har sløjfet alle dets underindstillinger, kan vi vende tilbage til det forrige niveau:

$parent = array_pop( $parent_stack );

Det er derfor, vi har gemt forældre-id'et i stakken!

Mit forslag er:overvej kodestykket ovenfor, og forstå det.

Spørgsmål er velkomne!

En af de fordele, jeg ser ved denne tilgang, er, at den eliminerer risikoen for at indgå i en uendelig løkke, som kan ske, når der bruges rekursion.



  1. Sådan tilføjer du et sidehoved og en sidefod til en formular i Microsoft Access

  2. Forbindelsen kan ikke castes til oracle.jdbc.OracleConnection

  3. Tilslutning af .NET på Linux til en ODBC-datakilde

  4. FGCB_ADD_REMOVE-låsen