【问题标题】:Creating php arrays from sql queries从 sql 查询创建 php 数组
【发布时间】:2009-12-11 10:17:01
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

    标签: php sql arrays


    【解决方案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 的列类型。

    【讨论】:

    • 我认为它真的接近工作,但我现在得到这个错误消息注意:未定义的偏移量:373 in sitemap2.php on line 24 menu nr 373 must be an array 查询返回373行,所以最后一个正在做一些有趣的事情。有什么想法吗?
    • sitemap2.php 的第 24 行是什么?
    • 嗯...它似乎将索引从 0 而不是 1 开始的东西放入菜单中。你能相应地调整你的 for 循环吗(到for ( $i = 0; $i &lt; count ( $menu ); $i++ )
    • 在 php 数组从偏移量 0 开始,Dominic 评论中的建议将修复错误。
    • 这会以某种方式破坏所有输出,但让 count($menu)-1 似乎有效。但是,新问题 - 它不会生成任何子菜单,只会生成顶层 :x
    【解决方案2】:

    我看到您的数组的索引从 [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

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

    解决方法:for ($i = 0;$i

    从0开始一直到399(严格

    【讨论】:

    • 嗨,我的数组只到 340,不太确定你从哪里得到 399!上面的答案中也发现了计数问题,但还不是很固定。
    【解决方案3】:

    我会用另一种方式来做:面向对象。

    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。

    【讨论】:

      猜你喜欢
      • 2011-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 2015-09-07
      • 1970-01-01
      • 2016-12-07
      相关资源
      最近更新 更多