sql >> Database >  >> RDS >> Mysql

Hoe een onbeperkt menuniveau te bouwen via PHP en mysql

Hier is een "ontwikkelaarvriendelijke" versie van de "één zoekopdracht , geen recursie " oplossing voor dit probleem.

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;

U hoeft alleen het gebruik van de variabele $parent_stack te begrijpen.

Het is een "LIFO"-stack (Last In, First Out) - de afbeelding in het Wikipedia-artikel zegt meer dan duizend woorden:http://en.wikipedia.org/wiki/LIFO_%28computing%29

Als een menuoptie subopties heeft, slaan we de bovenliggende ID op in de stapel:

array_push( $parent_stack, $parent );

En dan werken we $parent onmiddellijk bij, waardoor het de huidige menu-optie-ID wordt:

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

Nadat we alle subopties hebben doorlopen, kunnen we terugkeren naar het vorige niveau:

$parent = array_pop( $parent_stack );

Daarom hebben we de ouder-ID in de stapel opgeslagen!

Mijn suggestie is:overweeg het bovenstaande codefragment en begrijp het.

Vragen zijn welkom!

Een van de voordelen die ik in deze benadering zie, is dat het het risico elimineert dat je in een oneindige lus terechtkomt, wat kan gebeuren wanneer recursie wordt gebruikt.



  1. Active Data Guard Physical Standby instellen in RAC One Node Architecture - Deel 2

  2. Hoe u alle beperkingen van CHECK en externe sleutels in een database in SQL Server inschakelt (T-SQL-voorbeelden)

  3. Een gegevensmodel voor een makelaarskantoor

  4. Hoe een kolomnaam in SQL te hernoemen?