开发者

Creating php arrays from sql queries

开发者 https://www.devze.com 2022-12-14 05:50 出处:网络
I\'m trying to create an array of arrays so I can build a dynamic menu, but I\'m getting lost amongst the code. My output looks like this:

I'm trying to create an array of arrays so I can build a dynamic menu, but I'm getting lost amongst the code. My output looks like this:

$menu = Array ( 
        [0] => Array ( 
            [text] => Home 
            [class] => 875 
            [link] => //Home 
            [show_condition] => TRUE 
            [parent] => 0 
            ) 
        [1] => Array ( 
            [text] => About 
            [class] => 326 
            [link] => //About 
            [show_condition] => TRUE 
            [parent] => 0 
            ) 
         etc 
         etc 
         etc       
        [339] => Array ( 
            [text] => Planner 
            [class] => 921 
            [link] => //Planner 
            [show_condition] => TRUE 
            [parent] => 45 
            ) 
    ) 

And the two functions which should build the menu are:

    function build_menu ( $menu )   {
            $out = '<div class="container4">' . "\n";
            $out .= '   <div class="menu4">' . "\n";
            $out .= "\n".'<ul>' . "\n";

            for ( $i = 1; $i <= count ( $menu )-1; $i++ )
            {

if ( is_array ( $menu开发者_运维知识库 [ $i ] ) ) {//must be by construction but let's keep the errors home
                    if ( $menu [ $i ] [ 'show_condition' ] && $menu [ $i ] [ 'parent' ] == 0 ) {//are we allowed to see this menu?
                        $out .= '<li class="' . $menu [ $i ] [ 'class' ] . '"><a href="' . $menu [ $i ] [ 'link' ] . '">';
                        $out .= $menu [ $i ] [ 'text' ];
                        $out .= '</a>';
                        $out .= get_childs ( $menu, $i );
                        $out .= '</li>' . "\n";
                    }
                }
                else {
                    die ( sprintf ( 'menu nr %s must be an array', $i ) );
                }
            }

            $out .= '</ul>'."\n";
            $out .= "\n\t" . '</div>';
            return $out . "\n\t" . '</div>';
        }

    function get_childs ( $menu, $el_id )   {
            $has_subcats = FALSE;
            $out = '';
            $out .= "\n".'  <ul>' . "\n";
            for ( $i = 1; $i <= count ( $menu )-1; $i++ )
            {

                if ( $menu [ $i ] [ 'show_condition' ] && $menu [ $i ] [ 'parent' ] == $el_id ) {//are we allowed to see this menu?
                    $has_subcats = TRUE;
                    $add_class = ( get_childs ( $menu, $i ) != FALSE ) ? ' subsubl' : '';
                    $out .= '       <li class="' . $menu [ $i ] [ 'class' ] . $add_class . '"><a href="' . $menu [ $i ] [ 'link' ] . '">';
                    $out .= $menu [ $i ] [ 'text' ];
                    $out .= '</a>';
                    $out .= get_childs ( $menu, $i );
                    $out .= '</li>' . "\n";
                }
            }
            $out .= '   </ul>'."\n";
            return ( $has_subcats ) ? $out : FALSE;
        }

But the menu is refusing to show any submenu levels - it only displays top level. Any ideas?

Thanks!


Your code is almost there - you may want to change mysql_fetch_array to mysql_fetch_assoc, and you can convert values as returned into the appropriate types using functions like intval:

$menu = array();
$sql = "SELECT TabName as text, TabID as class, TabPath as link, IsVisible as show_condition, ParentId as parent FROM dnn_SMA_Tabs WHERE PortalID = 3 AND IsVisible = 'True' ORDER BY TabOrder ASC";
$result = mysql_query($sql);
$index = 1;
while($row = mysql_fetch_assoc($result)) {
    $row['parent'] = intval($row['parent']);
    $menu[$index] = $row;
    $index++;
}

You'll need to convert show_condition to the appropriate type - how to do that probably depends on what column type IsVisible is.


i see your array has indexes from [0] to [399]

Array (

[0] => Array ( 
    [text] => Home 
    [class] => 875 
    [link] => //Home 
    [show_condition] => TRUE 
    [parent] => 0 
    ) 
[1] => Array ( 
    [text] => About 
    [class] => 326 
    [link] => //About 
    [show_condition] => TRUE 
    [parent] => 0 
    ) 
 etc 
 etc 
 etc       
[339] => Array ( 
    [text] => Planner 
    [class] => 921 
    [link] => //Planner 
    [show_condition] => TRUE 
    [parent] => 45 
    )  )

but you try to show items from [1] to [340]

for ( $i = 1; $i <= count ( $menu ); $i++ )

count($menu) returns 340 ([0]->[399])

Solution: for ( $i = 0; $i < count ( $menu ); $i++ )

start from 0 and go until 399 (strictly < 340)


I would do it in an other way: object oriented.

class Menu {
  private $children = array();
  private $name = '';
  private $link = '';
  private $class = '';
  private $show = TRUE;

  function __construct($name, $class, $link, $show = TRUE, $parent = null) {
    $this->name = $name;
    $this->link = $link;
    $this->class = $class;
    $this->show = $show;
    if(!is_null($parent)) {
        $parent->addChild($this);
    }
  }

  function addChild(Menu $child) {
      $this->children[] = $child;
  }

  // ... remaining getters (and probably setters)
}

Then you can build the menu like this:

$home = new Menu('Home', '875', '//Home');
$about = new Menu('About', '326', '//About');

//...

$planner = new Menu('Planner', '921', '//Planner', true, $home);

$menu = array($home, $about,...);

This is just one example. I am aware that this would mean you create 340 variables to hold your menu. With other setter and getter methods you can do it better, this is just a fast 'sketch'.

You can build the menu like this:

function build_menu ( $menu, $showContainer = false)   {
    $out = '';
    if($showContainer) {
        $out = '<div class="container4">' . "\n";
        $out .= '       <div class="menu4">' . "\n";              
    }

    if(!empty($menu)) {
        $out .= '<ul>' . "\n";

        for ($entry in  $menu) {
            if($entry->getShow()) {//are we allowed to see this menu?
                 $out .= '<li class="' . $entry->getClass() . '"><a href="' . $entry->getLink() . '">';
                 $out .= $entry->getText();
                 $out .= '</a>';
                 $out .= "\n" . build_menu($entry->getChildren());
                 $out .= '</li>' . "\n";
             }
        }
        $out .= '</ul>'."\n";
    }
    if($showContainer) {
        $out .= "\n\t" . '</div>';
        $out .= "\n\t" . '</div>';                
    }
    return $out;
}

I didn't test the code, but this is the idea behind it. If you have no experience with OOP and php have a look at the official documentation.

And also note that this requires PHP5.

0

精彩评论

暂无评论...
验证码 换一张
取 消