从sql查询创建php数组

时间:2009-12-11 10:17:01

标签: php sql arrays

我正在尝试创建一个数组数组,以便我可以构建一个动态菜单,但我在代码中迷失了方向。我的输出如下:

$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 
            ) 
    ) 

应该构建菜单的两个函数是:

    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;
        }

但菜单拒绝显示任何子菜单级别 - 它只显示顶级。有什么想法吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

您的代码几乎就在那里 - 您可能希望将mysql_fetch_array更改为mysql_fetch_assoc,并且可以使用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++;
}

您需要将show_condition转换为适当的类型 - 如何做到这可能取决于IsVisible的列类型。

答案 1 :(得分:0)

我看到你的数组的索引从[0]到[399]

  

数组(

[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 
    )  )

但您尝试显示[1]至[340]

中的项目
  

for($ i = 1; $ i&lt; = count($ menu); $ i ++)

count($ menu)返回340([0] - &gt; [399])

解决方案:for($ i = 0; $ i&lt; count($ menu); $ i ++)

从0开始直到399(严格<340)

答案 2 :(得分:0)

我会以另一种方式做到这一点:面向对象。

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)
}

然后你可以像这样建立菜单:

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

//...

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

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

这只是一个例子。我知道这意味着你创建340个变量来保存你的菜单。使用其他setter和getter方法,您可以做得更好,这只是一个快速的“草图”。

您可以像这样构建菜单:

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;
}

我没有测试代码,但这背后的想法。如果您没有使用OOP的经验,那么php会查看official documentation

还要注意这需要PHP5。