使用MySQL数据库进行PHP导航

使用MySQL数据库进行PHP导航,php,mysql,Php,Mysql,我在需要MySQL数据库的地方做了一个导航。 这是我与数据库的连接,以获取所有信息 $stmt = $pdo->prepare("SELECT * FROM navigation"); $stmt->execute(); $results = $stmt->fetchAll(PDO::FETCH_OBJ); if($stmt->rowCount() > 0){ $primary_nav = []; foreach ($result

我在需要MySQL数据库的地方做了一个导航。 这是我与数据库的连接,以获取所有信息

$stmt = $pdo->prepare("SELECT * FROM navigation");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if($stmt->rowCount() > 0){
    $primary_nav = [];
    foreach ($results as $result){
        if($result->sub == 0){
            $primary_nav[] = array(
                'name'  => $result->name,
                'url'   => $result->url,
                'icon'  => $result->icon,
            );
        }elseif($result->sub == 1){
            $primary_nav[] = array(
                'name'  => $result->name,
                'icon'  => $result->icon,
                'sub'   => array(
                    array(
                        'name'  => $result->name_sub,
                        'url'   => $result->url_sub
                    )
                )
            );
        }
    }
}
这很好,如果我把导航添加到数据库中,一切看起来都很完美,效果也很好。 现在的问题是,当我想要一个新的子菜单时,而不是每次我得到一个只有一个子菜单的新的顶部菜单

所以我的问题是,我如何在不破坏代码的情况下让这部分工作。 通常代码如下所示:

// first sub
array(
    'name'  => 'Test1',
    'icon'  => 'fa fa-bullhorn',
    'sub'   => array(
        array(
            'name'  => 'First Sub 1',
            'url'   => 'sub1.php'
        ),
        array(
            'name'  => 'First Sub 2',
            'url'   => 'sub2.php'
        )
    )
),
// second sub
array(
    'name'  => 'Test3',
    'icon'  => 'fa fa-bullhorn',
    'sub'   => array(
        array(
            'name'  => 'Second Sub',
            'url'   => 'sub1_1.php'
        )
    )
)
Test1
-- First Sub 1
Test2 (it would be empty because in the database it is empty just for example I puted Test2)
-- First Sub 2
Test3
-- Second Sub
数据库结构:

|-----name-----|----url----|----icon----|----sub----|----name_sub----|----url_sub----|----category----|
|  Dashboard  | index.php |    icon    |     0     |                |               |                |
------------------------------------------------------------------------------------------------------
|    Test     | test.php  |    icon    |     0     |                |               |                |
------------------------------------------------------------------------------------------------------
|    Test1    |           |    icon    |     1     |    First Sub 1 |   sub1.php    |       1        |
------------------------------------------------------------------------------------------------------
|             |           |    icon    |     1     |    First Sub 2 |   sub2.php    |       1        |
------------------------------------------------------------------------------------------------------
|    Test3    |           |    icon    |     1     |    Second Sub  |  sub1_1.php   |       2        |
------------------------------------------------------------------------------------------------------**
因此,如果类别与另一个类别的数字相同,则应该这样做:

Test1
-- First Sub 1
-- First Sub 2
Test3
-- Second Sub
但我的代码看起来是这样的:

// first sub
array(
    'name'  => 'Test1',
    'icon'  => 'fa fa-bullhorn',
    'sub'   => array(
        array(
            'name'  => 'First Sub 1',
            'url'   => 'sub1.php'
        ),
        array(
            'name'  => 'First Sub 2',
            'url'   => 'sub2.php'
        )
    )
),
// second sub
array(
    'name'  => 'Test3',
    'icon'  => 'fa fa-bullhorn',
    'sub'   => array(
        array(
            'name'  => 'Second Sub',
            'url'   => 'sub1_1.php'
        )
    )
)
Test1
-- First Sub 1
Test2 (it would be empty because in the database it is empty just for example I puted Test2)
-- First Sub 2
Test3
-- Second Sub
也许有人能理解我的需要,因为我的英语不是最好的解释。感谢您对此问题的任何帮助/解决方案

$stmt = $pdo->prepare("SELECT * FROM navigation");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
if($stmt->rowCount() > 0){

    $categories = [];
    $primary_nav = [];

    foreach ($results as $result){

        if ($result->name) {

            if ($result->category) {
                $categories[$result->category] = sizeof($primary_nav);
            }

            $primary_nav[] = array(
                'name'  => $result->name,
                'url'   => $result->url,
                'icon'  => $result->icon,
            );

        }

        if ($result->name_sub) {
            $primary_nav[$categories[$result->category]]['sub'][] = array(
                'name'  => $result->name_sub,
                'url'   => $result->url_sub
            );
        }

    }
    
}
我添加了一个额外的
$categories
数组

对于每个具有类别的“父”条目,
$categories
数组将数据库中的类别值和“父”条目的键存储在
$primary\u nav
数组中。 然后可以使用
$categories
数组使用其类别值将后续子类别添加到正确的父条目中

但是,在当前设置中,数据库允许您拥有没有父类别的子类别和没有名称的(子)类别。 因此,我建议使用如下表格设置:

id      name        url         icon    parent

1       Dashboard   index.php   icon    null
2       Test        test.php    icon    null
3       Test1       null        icon    null
4       First sub 1 sub1.php    null    3
5       First sub 2 sub2.php    null    3
6       Test3       null        icon    null
7       Second sub  Sub1_1.php  null    6
父类别的“Parent”列设置为null,子类别的“Parent”列设置为父条目的id。 这还允许您拥有子类别(等等)

您需要递归地查询它:

function buildNav($pdo, $id = null) {
    $array = [];
    
    if ($id) {
        $stmt = $pdo->prepare("SELECT * FROM navigation WHERE parent = :id");
        $stmt->bindValue('id', $id);
    } else {
        $stmt = $pdo->prepare("SELECT * FROM navigation WHERE parent IS NULL");
    }
    
    $stmt->execute();
    $results = $stmt->fetchAll(PDO::FETCH_OBJ);
    
    if ($stmt->rowCount() > 0){
        foreach ($results as $result){
            $array[] = array(
                'name'  => $result->name,
                'url'   => $result->url,
                'icon'  => $result->icon,
                'sub'   => buildNav($pdo, $result->id)
            );
        }
    }
    
    return $array;
}

$primary_nav = buildNav($pdo);

谢谢你令人惊讶的回答。这对我帮助很大!