Динамическое меню = управляемая база данных Php

Вот скрипт для неупорядоченного списка, основанный на пользовательских данных и базе данных, для PHP5 5.3.10 Как вы можете видеть, этот метод происходит из процедурного фона.

Ему около года, и сегодня я подумал написать его еще раз, данные для этого скрипта взяты только из одной таблицы SQL; запускается классом dao и несколькими открытыми функциями.

Этот код работает, как и ожидалось, но выглядит немного уродливо для меня, что вы думаете и куда бы вы пошли отсюда, если бы вы решили написать его снова?

В основном сценарий производит этот HTML:

<div class="menuInside" id="menu">
    <div>
        <ul class="">
            <li class="first"><a onclick="this.blur()" id="bienvenue" href="/bienvenue.html"><img width="109" height="19" alt="Bienvenue" src="/images/menu/bienvenue.png"></a></li>
            <li class="text"><a href="/bienvenue.html">Nous sommes heureux de vous accueillir sur notre site Internet.</a></li>
        </ul>
    </div>
    <div>
        <ul class="insidemiddle ulactive">
            <li class="second"><a onclick="this.blur()" id="marques" href="/lingerie-feminine.html"><img width="102" height="23" alt="Marques" src="/images/menu/marques.png"></a></li>
            <li class="elements"><a href="/barbara.html">Barbara</a></li>
            <li class="elements"><a href="/calida.html">Calida</a></li>
            <li class="elements"><a href="/canat.html">Canat</a></li>
            <li class="elements"><a href="/chantelle.html">Chantelle</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elements"><a href="/charmline-lidea.html">Charmline &amp; Lidea</a></li>
            <li class="elements"><a href="/eminence.html">Eminence</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elements"><a href="/empreinte.html">Empreinte</a></li>
            <li class="elementsOne"><a href="/lisanza.html">Lisanza</a></li>
            <li class="elements"><a href="/lise-charmel.html">Lise Charmel</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elements"><a href="/lou.html">Lou</a></li>
            <li class="elementsThree"><a href="/marjolaine.html">Marjolaine</a></li>
            <li class="elements"><a href="/pain-de-sucre.html">Pain de Sucre</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elements"><a href="/rcrescentini.html">R. Crescentini</a></li>
            <li class="elements"><a class="active" href="/save-the-queen.html">Save The Queen</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elements"><a href="/secret-eva.html">Secret d'Eva</a></li>
            <li class="elements"><a href="/trasparenze.html">Trasparenze</a></li>
            <li class="elements"><a href="/triumph.html">Triumph</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elements"><a href="/twin-set.html">Twin Set</a></li>
        </ul>
    </div>
    <div>
        <ul class="insidemiddle">
            <li class="first"><a onclick="this.blur()" id="lingerie" href="/lingerie-feminine.html"><img width="88" height="21" alt="Lingerie" src="/images/menu/lingerie.png"></a></li>
            <li class="elementsOne"><a href="/lingerie-feminine.html">Féminin</a></li>
            <li class="elements"><a href="/lingerie-masculine.html">Masculin</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elementsTwo"><a href="/lingerie-de-nuit.html">Linge de Nuit</a></li>
            <li class="elements"><a href="/articles-balneaires.html">Articles Balnéaires</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elementsNine"><a href="/collants-bas-mi_bas-chaussettes.html">Collants, Bas, Mi-bas, Chaussettes...</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
            <li class="elementsTen"><a href="/laine-et-soie.html">Laine et Soie</a><img width="9" height="9" class="last" alt="" src="/images/menu/menu_item.png"></li>
        </ul>
    </div>
    <div>
        <ul class="">
            <li class="first"><a onclick="this.blur()" id="contact" href="/contact.html"><img width="106" height="19" alt="Contact" src="/images/menu/contact.png"></a></li>
            <li class="text"><a href="/contact.html">Si vous souhaitez nous faire part de vos impressions ou pour tout autre commentaire...<br>
                <br>
                Nos horaires d'ouvertures</a></li>
        </ul>
    </div>
</div>

Хотели бы вы указать мне правильное направление?

Вот сценарий:

<?php
$id=isset($_GET['id'])?$_GET['id']:1;
($id!=1)?$classNav='menuInside':$classNav='menu';
?>

<div id="menu" class="<?=$classNav?>"><?php $cliao=new cliao();
    $ActiveNav_result=$cliao->SubNav(array(" display_block"=>'=1'," id_marque"=>'='.$id),"id_menu",1);
    $ActiveNav_item=$cliao->fetchResult($ActiveNav_result);
    $Nav_result=$cliao->Nav(array(" display_block"=>'=1'),"id_menu");
    while($MainNav_items=$cliao->fetchResult($Nav_result)){$SubNav_result=$cliao->SubNav(array(" display_block"=>"=1"," id_menu"=>'='.$MainNav_items->id_menu),"id_menu",1);
        if($classNav!="menu"){($MainNav_items->Nav_type==1)?$class='insidemiddle':$class='';
            ($ActiveNav_item->id_Nav==$MainNav_items->id_menu)?$class.=' ulactive':$class.='';
            echo '<div><ul class="'. $class .'">'."\n";
        }else{
            ($MainNav_items->Nav_type==1)?$class='ulactive middle':$class='ulactive';
                echo '<div><ul class="'.$class.'">'."\n";
        }
    while($MainSubNav_items=$cliao->fetchResult($SubNav_result)){
        ($MainNav_items->class_block==2)?$firstclass='class="first"': $firstclass='class="second"';
        echo ($MainNav_items->display_block==1)?'<li '.$firstclass.'><a href="'.$MainNav_items->href_link.'" id="'.$MainNav_items->name.'" onclick="this.blur()"><img src="/images/menu/'.$MainNav_items->name.'.png" alt="'.ucfirst($MainNav_items->name).'" width="'.$MainNav_items->image_width.'" height="'.$MainNav_items->image_height.'" /></a></li>'."\n":'';
        }
        $SubNav_result=$cliao->SubNav(array(" display_block"=>"=1"," id_menu"=>'='.$MainNav_items->id_Nav),"id_menu");
    while($MainSubNav_items=$cliao->fetchResult($SubNav_result)){($MainSubNav_items->Nav_last=="yes")?$last='<img src="/images/menu/menu_item.png" alt="" width="9" height="9" class="last" />':$last='';
        ($MainSubNav_items->id_marque==$id)?$activeclass='class="active"':$activeclass='';
?>
        <li class="<?=$MainSubNav_items->Nav_class?>"><a href="<?=$MainSubNav_items->href_link?>" <?=$activeclass?>><?=$MainSubNav_items->text?></a><?=$last?></li><?="\n"?><?php }echo '</ul></div>'."\n";
    }
?>
</div>

1 ответ

Я всегда стараюсь по возможности связывать содержимое моей базы данных с генерируемым HTML. Например, вместо:

if($classNav!="menu"){($MainNav_items->Nav_type==1)?$class='insidemiddle':$class='';
        ($ActiveNav_item->id_Nav==$MainNav_items->id_menu)?$class.=' ulactive':$class.='';
        echo '<div><ul class="'. $class .'">'."\n";
    }else{
        ($MainNav_items->Nav_type==1)?$class='ulactive middle':$class='ulactive';
            echo '<div><ul class="'.$class.'">'."\n";
    }

Я бы сохранил желаемый финал $ClassNav в базе данных и напишите это так:

echo '<ul class='$ClassNav'>\n';

Я бы также пропустил грязный class='first' ерунду и по возможности используйте первые дочерние псевдоэлементы CSS.

Я вижу, вы используете while много. Я не виню вас, именно так поступают 90% руководств по PHP (и пример кода на PHP.net). Однако это не идеально, потому что:

  1. он опирается на непостижимый и неуклюжий внутренний указатель строк, возможно, наименее интуитивный метод навигации по массивам, и
  2. в результате вы должны написать много смешного, как наворот $MainSubNav_items=$cliao->fetchResult($SubNav_result),

Сделай свою жизнь проще. Сначала преобразуйте данные в массив, а затем либо получите к нему доступ foreach ($data as $record) { $out .= $record['fieldname']; } или же for ($i = 0; $i < sizeOf($record); $i++) { $out .= $record[$i]['fieldname']; },

В этом сравнении foreach является более кратким, тогда как for дает вам больше доступа к управлению потоком.

Наконец, рассмотрите возможность переписать это как рекурсивную функцию: ту, которая рендерится через список, и когда она встречает подменю, вызывает себя для генерации следующего уровня. Намного проще, намного надежнее.:)

Например, вот код генерации меню, который я использую в своем (внутреннем) объектно-ориентированном инструментарии:

public function Render($Menu = false){ 
    $Menu = (is_array($Menu) ? $Menu : $this->MainMenu); // If no menu array is passed, pull the main menu object from the class constructor
    $Out = "<ul class='SuuiMenu'>"; //building an $Out string instead of echoing is preferable as the resulting function can be used in more contexts

    foreach ($Menu as $Entry){
        if ($Entry['Link'] !== '#'){ //I use a link value of # for submenu headers
            $Entry['Link'] = base_url().$Entry['Link'];
        }
        $Out .= "
            <li>
                <a href='{$Entry['Link']}'>{$Entry['Title']}</a>";
            if (isset($Entry['Children'])){ //if this menu entry has 'Children' in its array, this method calls itself with that child's array as an argument and adds the whole thing to $Out
                $Out .= $this->Render($Entry['Children'], false);
            }   
        $Out .="</li>
        ";
    }

    $Out .= "</ul>";

    return $Out; //to be echoed, modified further in PHP-DOM, cached, etc :)
}
Другие вопросы по тегам