यहां "एक क्वेरी . का "डेवलपर के अनुकूल" संस्करण दिया गया है , कोई पुनरावर्तन नहीं "इस समस्या का समाधान।
एसक्यूएल :
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;
आपको बस $parent_stack वेरिएबल के उपयोग को समझने की जरूरत है।
यह एक "LIFO" स्टैक है (लास्ट इन, फर्स्ट आउट) - विकिपीडिया लेख में छवि एक हजार शब्दों के लायक है:http://en.wikipedia.org/wiki/LIFO_%28computing%29
जब किसी मेनू विकल्प में उप-विकल्प होते हैं, तो हम उसकी पैरेंट आईडी को स्टैक में संग्रहीत करते हैं:
array_push( $parent_stack, $parent );
और फिर, हम तुरंत $parent को अपडेट करते हैं, जिससे यह वर्तमान मेनू विकल्प आईडी बन जाता है:
$parent = $option['value']['id'];
इसके सभी उप-विकल्पों को लूप करने के बाद, हम पिछले स्तर पर वापस लौट सकते हैं:
$parent = array_pop( $parent_stack );
यही कारण है कि हमने पैरेंट आईडी को स्टैक में संग्रहीत किया है!
मेरा सुझाव है:ऊपर दिए गए कोड स्निपेट पर विचार करें और इसे समझें।
प्रश्नों का स्वागत है!
इस दृष्टिकोण में मुझे जो लाभ दिखाई देता है, उनमें से एक यह है कि यह एक अनंत लूप में प्रवेश करने के जोखिम को समाप्त करता है, जो तब हो सकता है जब रिकर्सन का उपयोग किया जाता है।