PHP और mysql के माध्यम से मेनू के असीमित स्तर को कैसे बनाया जाए



3 Answers

यहां इस समस्या के लिए " एक क्वेरी , कोई पुनरावर्ती " समाधान का "डेवलपर-अनुकूल" संस्करण नहीं है।

एसक्यूएल :

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 = $option['value']['id'];

इसके बाद हमने इसके सभी उप-विकल्प को रोक दिया, हम पिछले स्तर पर वापस लौट सकते हैं:

$parent = array_pop( $parent_stack );

यही कारण है कि हमने मूल आईडी को स्टैक में संग्रहीत किया है!

मेरा सुझाव है: ऊपर दिए गए कोड स्निपेट पर गौर करें, और इसे समझें।

प्रश्न का स्वागत है!

इस दृष्टिकोण में मैं देख रहा हूं कि यह एक अनंत लूप में प्रवेश करने के जोखिम को समाप्त करता है, जो तब हो सकता है जब recursion उपयोग किया जाता है।

Question

खैर, मेरे मेनू का मेन्यू बनाने के लिए मैं इस तरह से एक डीबी संरचना का उपयोग करता हूं

  2  Services                  0
  3  Photo Gallery             0
  4  Home                      0
  5  Feedback                  0
  6  FAQs                      0
  7  News & Events             0
  8  Testimonials              0
 81  FACN                      0
 83  Organisation Structure   81
 84  Constitution             81
 85  Council                  81
 86  IFAWPCA                  81
 87  Services                 81
 88  Publications             81

मौजूदा सबमेनू के लिए एक अन्य उपमेनू प्रदान करने के लिए मैं अपने माता पिता के आईडी को मूल फ़ील्ड के मान के रूप में निर्दिष्ट करता हूं। माता पिता 0 का मतलब शीर्ष मेनू है

अब एक अन्य सबमेनू में सबमेनू बनाते समय समस्या नहीं है

अब यह तरीका है कि मैं शीर्ष मेनू के लिए सबमेनू ले आता हूं

<ul class="topmenu">
    <? $list = $obj -> childmenu($parentid); 
        //this list contains the array of submenu under $parendid
        foreach($list as $menu) {
            extract($menu);
            echo '<li><a href="#">'.$name.'</a></li>';
        }
    ?>
</ul>

मैं क्या करना चाहता हूं

मैं यह जानना चाहता हूं कि कोई नया मेनू दूसरे बाल मेनू है या नहीं

और मैं जब तक यह उपलब्ध हर बच्चे मेनू को खोजता है, तब तक जांच करना जारी रखना चाहता हूं

और मैं इस तरह अपने विशेष सूची आइटम के अंदर अपने बाल मेनू प्रदर्शित करना चाहता हूँ

<ul>       
       <li><a href="#">Home</a>
        <ul class="submenu">
           ........ <!-- Its sub menu -->
           </ul>
       </li>
</ul>



http://pastebin.com/ariBn3pE

आपको रिकर्सन का उपयोग करने की आवश्यकता है, लेकिन मेरा दृष्टिकोण अलग है, मैंने प्रत्येक मेनू को अलग-अलग संभाल करने के लिए एक वर्ग बनाया है, फिर परिणाम के लिए पूछताछ किया है और प्रत्येक तत्व के समूह में उनके माता-पिता के अनुसार, प्रत्येक स्तर के अनुसार, और फिर सभी वस्तुओं एक में ... पूर्ण कोड के लिए पेस्टबिन को चेक करें




मैंने इस तरह से पाया, वाई फ़्रेमवर्क के साथ काम करना

$children = array();

foreach($model as $k => $item){
    if(empty($item->cn_id_menu_padre))
        $children[$item->cn_id] = $item->attributes;
    else
        $children[$item->cn_id_menu_padre]['hijos'][] = $item->attributes;
}

foreach($children as $k=>$child){
    if(array_key_exists('hijos',$child))
    {
        echo 'li y dentro ul<br>';
        foreach($child['hijos'] as $hijo){
            echo 'li<br>';
        }
    }
    else
        echo 'li<br>';
}

अगर आपको एक और स्तर की आवश्यकता है, तो आप बच्चों के hijos_de_hijos को दूसरे स्तर पर बना सकते हैं जैसे कि hijos_de_hijos और तुलना करें तो अगर hijos_de_hijos

ओह, ज़ाहिर है, तुलना करने के लिए अगर cn_id_menu_padre खाली है, डेटाबेस में मान null होना चाहिए।




मैं सुझाव दूंगा कि आप पूर्व-आदेशित वृक्ष ट्रांज़ैशल पर गौर करें। इस मुद्दे पर इस पर एक लेख है:

MySQL में पदानुक्रमित डेटा प्रबंधित करना

प्रभावी रूप से, आप प्रत्येक पृष्ठ को 'नोड' के रूप में लेते हैं प्रत्येक नोड के माता-पिता के लिए एक संदर्भ है। जब आप नोड्स का लेआउट बदलते हैं (एक बच्चा जोड़ें, नोड्स ले जाएं, आदि), तो आप प्रत्येक नोड के लिए एक 'बाएं' और 'दाएं' मान की पुनर्गणना करते हैं (उपरोक्त आलेख यह पीएचपी में स्रोत कोड के लिंक के साथ महान विवरण में बताता है )। आप के साथ क्या समाप्त होता है, यह बहुत जल्दी निर्धारित करने की क्षमता है कि यदि कोई नोड किसी अन्य नोड का प्रत्यक्ष या अप्रत्यक्ष बच्चा है, साथ ही किसी दिए गए नोड के सभी बच्चे नोड प्राप्त करें।




Related



Tags

php php   mysql mysql   menu