在数组元素内计算数组的大小 - PHP

时间:2013-12-19 14:23:08

标签: php arrays multidimensional-array count

所以我正在尝试创建一个动态导航栏,它通过存储在数据库中的菜单项构建。

每个菜单项都分配了一个parent_id,如果该id为0,则该项为父项;如果该id是大于0的值,则该菜单项是另一个菜单项的子项。 (想象一下,将鼠标悬停在导航菜单项上并下载儿童项目)

以下函数用于根据数据库中的记录构建多维数组。

function build_menu($menu_id){
    $mysqli = new mysqli("localhost", "user", "password", "db");
    if($mysqli->connect_errno){
        echo "Failed to connect to MySQL: " . $mysqli->connect_errno;
    }

    $stmt = $mysqli->prepare("SELECT `id`, `name`, `order`, `parent_id`, `path` FROM menu_items WHERE `group_id` = ? ORDER BY `order` ASC");
    $menu_id = intval($mysqli->real_escape_string($menu_id));
    $stmt->bind_param('i', $menu_id);
    if($stmt->execute()){
        $results = resultToArray($stmt->get_result());
        $parents = array();
        $children = array();
        $menu = array();
        for($i=0; $i<count($results); $i++){
            if($results[$i]['parent_id'] === 0){
                $parents[] = $results[$i];
            } else {
                $children[] = $results[$i];
            }
        }

        for($i=0; $i<count($parents); $i++){
            $menu[$i] = $parents[$i];
            for($j=0; $j<count($children); $j++){
                if($children[$j]['parent_id'] === $parents[$i]['id']){
                    $menu[$i][$j] = $children[$j];
                }
            }
        }
        return($menu);
    } else {
        echo "Failed to execute statement: " . $stmt->errno . ": " . $stmt->error;
    }
    $mysqli->close();
    return(0);
}

这是获取该数组并将其转换为HTML代码以用作导航栏的函数。

function get_menu($menu_id) {
    if(build_menu($menu_id)){
        $menu = build_menu($menu_id);

        $menu_html = '<ul>';
        for($i=0; $i<count($menu); $i++){
            $menu_item_path = ($menu[$i]['path'] != NULL ? $menu[$i]['path'] : '#');
            $menu_html .= '<li><a href="' . $menu_item_path . '">' . $menu[$i]['name'] . '</a>';
            if(count($menu[$i])>0){
                $menu_html .= '<ul>';
                for($j=0; $j<count($menu[$i]); $j++){
                    if(isset($menu[$i][$j])){
                        $menu_html .= '<li>' . $menu[$i][$j]['name'] . '</li>';
                    }
                }
                $menu_html .= '</ul>';
            }
            $menu_html .= '</li>';
        }
        $menu_html .= '</ul>';

        return($menu_html);
    }
    }

我假设if(count($menu[$i])>0)会计算所选元素中的数组,但由于某种原因,它会对键进行计数,因此始终为真。

我知道这是一个很长的问题,我非常感谢那些读过这篇文章的人。如果你可以帮我找出一种方法来查看菜单项是否包含子项,那就太棒了。

2 个答案:

答案 0 :(得分:0)

使用array_filter仅计算数组中的项目不为空或为空

答案 1 :(得分:0)

生成HTML菜单的过程比您的示例容易得多。

function generateMenu(array $menu, $parentId = 0) {
    if (!isset($menu[$parentId])) {
        return;
    }
    $output = '<ul>';
    foreach ($menu[$parentId] as $record) {
        $output .= '<li>';
        $output .= '<a href="#">' . $record['title'] . '</a>';
        $output .= generateMenu($menu, $record['id']);
        $output .= '</li>';
    }
    $output .= '</ul>';
    return $output;
}

echo generateMenu($menu);

上面的代码会输出HTML,如:

x First level #1
    o Second level #8
x First level #2
    o Second level #4
        - Third level #6
        - Third level #7
    o Second level #5
x First level #3

demo

但为了实现这一目标,您必须修复build_menu()函数,以返回this之类的数组,这非常简单,只需创建一个数组$menu并填充$menu[$row['parent_id']][] = $row; 1}},其中$row是从数据库中提取的记录行。