Skip navigation.
Home

That is some classy code...

Hall of Fame | Bad Architecture | Fugly Code | Wonky Code

Thanks to Andreas D. for sending this one in. This PHP code generates a heirachical menu in a not so nice way.

  • WTF #1 is for being very 'fugly' code. Nobody should indent with more than 4 spaces!
  • WTF #2 is the menu class. This class really has no point other than to hold two values which can be done with a simple array. See my example below.
  • WTF #3 is this $menu[$i][$j][0][0][0]->target. There's nothiing like a 5 dimensional array to make a really simple thing like menu generation really difficult.

Be sure to shield your eyes and don't look directly at this code...

<?php
class menu{
       var
$name;
       var
$target;

       function
menu($name, $target){
               
$this->name = $name;
               
$this->target = $target;
       }
}

function
drawMenu(){
       global
$menu, $active_menu;

       
$kat=$active_menu["kat"];

       while (list(
$i) = each($menu)) {
               if (
$i == $kat) {
                       
//category title
                       //PrintMenuTitle($menu[$i][0][0][0][0]->name);
                       
$menu[$i][0][0][0][0]->name;

                       
//level-1
                       
while (list($j) = each($menu[$kat])) {
                               if (
$j > 0) {
                                       
PrintMenu(1, $menu[$i][$j][0][0][0]->name, $menu[$i][$j][0][0][0]->target, (($j == $active_menu["sub1"]) ? 1 : 0));

                                       
//level-2
                                       
if ($j == $active_menu["sub1"]){
                                               while (list(
$k) = each($menu[$kat][$j])) {
                                                       if (
$k > 0) {
                                                               
PrintMenu(2, $menu[$i][$j][$k][0][0]->name, $menu[$i][$j][$k][0][0]->target, (($k == $active_menu["sub2"]) ? 1 : 0));

                                                               
//level-3
                                                               
if ($k == $active_menu["sub2"]){
                                                                       while (list(
$l) = each($menu[$kat][$j][$k])) {
                                                                               if (
$l > 0) PrintMenu(3, $menu[$i][$j][$k][$l][0]->name, $menu[$i][$j][$k][$l][0]->target, (($l == $active_menu["sub3"]) ? 1 : 0));
                                                                       }
                                                               }
                                                       }
                                               }
                                       }
                               }
                       }
                       
PrintEnding();
               }
       }
}

function
PrintMenu($level, $name, $target, $active) {

       switch (
$level) {
           case
1:
                                       
$width = 0;

                                       break;

           case
2:
                                       
$width = 15;
               break;

           case
3:
                                       
$width = 30;
               break;
       
/*
       case 3:
               $colspan = array(4,2,1);//421
                                       $size = "small";
                                       $width = 22;
                                       $width2 = 6;
                                       $align = "right";
                                       $arrowwidth = 3;
                                       $arrowheight = 5;
                                       $paddingtop = 6;
                                       $class = "subnav";

               break;

           case 4:
               $colspan = array(4,2,1);
               break;
*/
       
}

        
$highlight = (($active == 1) ? "on" : "off" );

       echo
'<tr>
                                       <td><img src="/_res/images/blank.gif" height="3" width="1"border="0" alt=""></td>
                               </tr>
                       </table>
                       <table border="0" cellspacing="0" cellpadding="0">
                               <tr>
                                       <td><img src="/_res/images/blank.gif" width="1" height="5" border="0" alt=""></td>
                                       <td valign="top" width="'
.$width.'"><img src="/_res/images/blank.gif" width="'.$width.'" height="1" border="0" alt=""></td>
                                       <td valign="top"><img src="/_res/images/nav/arrow_'
.$highlight.'.gif" width="7" height="7" border="0" vspace="4" alt="Arrow"></td>
                                       <td><img src="/_res/images/blank.gif" width="6" height="1" border="0" alt=""></td>
                                       <td><a href="'
.$target.'" class="navlink">'.$name.'</a></td>
                               </tr>'
;

}

function
PrintEnding() {
       echo
'</table>';
}
?>

phrax Recommends...

Usually when I do recursive menus I use arrays and do something like this. There are probably much better techniques but this is an example of something fairly simple.

<?php
/**************************************************************
  Some quick example code demonstrating how to
  generate a recursive menu script
**************************************************************/

function menu($name,$URL = null)
{
/* Helper function to reduce the number of times we have to
     type array(...). This also cuts down on the # of bugs
   */
    
return array('name' => $name,
                 
'URL'  => $URL,
                 
'children' => array() // blank for now.
                
);
}

function
printMenu(&$children)
{
    
// HTML here for the sake of example. Normally I would avoid
    // this. :)
    
echo '<ul>';
    foreach (
$children as $id => $child)
    {
        if (
$child['URL'] != null) {
            
printf('<li><a href="%s" id="%s">%s</a></li>',$child['URL'],
                
htmlentities($id),htmlentities($child['name']));
        } else {
            
printf('<li>%s</li>',htmlentities($child['name']));
        }
        echo
"\n"; // so we have some nice HTML :)
        
        // here's the recursion.
        
if (count($child['children']))
            
printMenu($child['children']);
    }
    echo
"</ul>\n";
}

// This is where we define the menu.
$menu = menu('Root','/');
$menu['children']['c1'] = menu('About PHPWTF','/about');

$menu['children']['c2'] = menu('Categories');
$menu['children']['c2']['children']['c2s1'] = menu('Wonky Code','/taxonomy/term/3');
$menu['children']['c2']['children']['c2s2'] = menu('Bad Architecture','/taxonomy/term/1');
$menu['children']['c2']['children']['c2s3'] = menu('Hall of Fame','/taxonomy/term/7');
// etc.

$menu['children']['c3'] = menu('RSS Feeds');
$menu['children']['c3']['children']['c3s1'] = menu('RSS');
$menu['children']['c3']['children']['c3s1']['children']['rss1'] = menu('RSS 0.92','/node/feed');
$menu['children']['c3']['children']['c3s1']['children']['rss2'] = menu('RSS 1.0','/index.rdf');
$menu['children']['c3']['children']['c3s1']['children']['rss3'] = menu('RSS 2.0','/rss2.xml');
$menu['children']['c3']['children']['c3s2'] = menu('Atom','/atom.xml');
// etc.

// recursion
printMenu($menu['children']);
?>

The above will generate this:

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

what if ... ... it those spa

what if ...

... it those spaces were tabs on their way, but then a simple text editor expanded 'em as spaces?

Definetly not! I originally

Definetly not! I originally opened the code in Zend Studio and it was as ugly as seen here! ;-)

Then this IDE shall be banned

Then this IDE shall be banned! And a tab is a tab, not 4, 8 or X spaces!

many kind of text editors hav

many kind of text editors having an option "convert tabs to spaces" - and by default it's enabled ...

UL tags are meant to be conta

UL tags are meant to be contained in LIs, in nested lists. It complicates things but far from invalidates your solution.

Hope this code makes its way back to the source!

Whoops. It should probably

Whoops. It should probably look like this:

<?php
function printMenu(&$children)
{
    
// HTML here for the sake of example. Normally I would avoid
    // this. :)
    
echo '<ul>';
    foreach (
$children as $id => $child)
    {
        echo
'<li>';
        if (
$child['URL'] != null) {
            
printf('<a href="%s" id="%s">%s</a>',$child['URL'],
                
htmlentities($id),htmlentities($child['name']));
        } else {
            
printf('%s',htmlentities($child['name']));
        }
        echo
"\n"; // so we have some nice HTML :)
        
        // here's the recursion.
        
if (count($child['children']))
            
printMenu($child['children']);
        
        echo
'</li>';     
    }
    echo
"</ul>\n";
}
?>

One thing I don't understan

One thing I don't understand is -- why use htmlentities() on pretty much everything you print into the HTML (and rightly so), then leave out the URI? If you're trying to put out anything resembling valid [X]HTML, the most irritating part of it is having unencoded ampersands in your links, but here you have a chance to nip the problem in the bud... :-)

P.S. -- Do the 'allowed HTML tags' only break in the preview, or are they actually simply rendered as plain text?

My personal WTF#4 is the po

My personal WTF#4 is the pointless printEnding() function! There is nothing like writing 4 lines of code for echoing "</table>". The argument of scalability does not count here, this code is everything else but scalable.

*shudder*, that makes my ey

*shudder*, that makes my eyes ache :-(

Nice example of recursion though. I used something similar for my catagory lists on my blog (pulled from a db, not an array but the technique is the same) : Recursive Catagories

Post new comment




*

  • Web and e-mail addresses are automatically converted into links.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre> <p> <br /> <br>