Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak zbudować nieograniczony poziom menu za pomocą PHP i mysql

Oto „przyjazna dla programistów” wersja „jedno zapytanie , brak rekurencji " rozwiązanie tego problemu.

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;

Musisz tylko zrozumieć użycie zmiennej $parent_stack.

Jest to stos „LIFO” (ostatnie weszło, pierwsze wyszło) – obraz w artykule w Wikipedii wart jest tysiąca słów:http://en.wikipedia.org/wiki/LIFO_%28computing%29

Gdy opcja menu ma podopcje, przechowujemy jej identyfikator rodzica na stosie:

array_push( $parent_stack, $parent );

A potem natychmiast aktualizujemy $parent, dzięki czemu będzie to bieżący identyfikator opcji menu:

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

Po zapętleniu wszystkich jego podopcji możemy wrócić do poprzedniego poziomu:

$parent = array_pop( $parent_stack );

Dlatego zapisaliśmy identyfikator rodzica na stosie!

Moja sugestia to:zastanów się nad powyższym fragmentem kodu i zrozum go.

Pytania są mile widziane!

Jedną z zalet tego podejścia jest to, że eliminuje ono ryzyko wejścia w nieskończoną pętlę, co może się zdarzyć, gdy używana jest rekurencja.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak wybrać n-ty wiersz w tabeli bazy danych SQL?

  2. Częste pytania i odpowiedzi dotyczące wywiadu MySQL dla nowszych i doświadczonych

  3. Jak mogę wyświetlić te same dane identyfikatora z pętlą while w PHP?

  4. Czy jest jakiś sposób na sprawdzenie wydajności indeksowania mysql?

  5. Jak korzystać z widoków w bazie danych MySQL