当前位置:首页 > PHP

php树形菜单的实现

2026-01-28 19:33:42PHP

PHP树形菜单的实现方法

实现树形菜单通常涉及数据库设计、数据查询和前端展示三个部分。以下是几种常见的实现方式:

邻接列表模型(Adjacency List)

这是最简单的树形结构存储方式,每个节点存储其父节点的ID。

// 数据库表结构示例
CREATE TABLE menu_items (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    parent_id INT NULL,
    FOREIGN KEY (parent_id) REFERENCES menu_items(id)
);

递归查询实现:

function buildTree(array $elements, $parentId = 0) {
    $branch = array();
    foreach ($elements as $element) {
        if ($element['parent_id'] == $parentId) {
            $children = buildTree($elements, $element['id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[] = $element;
        }
    }
    return $branch;
}

// 使用示例
$items = $pdo->query("SELECT * FROM menu_items")->fetchAll(PDO::FETCH_ASSOC);
$tree = buildTree($items);

嵌套集模型(Nested Set)

这种模型查询效率更高,但维护复杂。

CREATE TABLE menu_items (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    lft INT NOT NULL,
    rgt INT NOT NULL
);

查询实现:

function getTree($pdo) {
    $sql = "SELECT node.name, (COUNT(parent.name) - 1) AS depth
            FROM menu_items AS node,
                 menu_items AS parent
            WHERE node.lft BETWEEN parent.lft AND parent.rgt
            GROUP BY node.name, node.lft
            ORDER BY node.lft";
    return $pdo->query($sql)->fetchAll();
}

路径枚举(Path Enumeration)

存储从根到节点的完整路径。

CREATE TABLE menu_items (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    path VARCHAR(255) // 如 '1/4/7'
);

查询实现:

function getTree($pdo) {
    $items = $pdo->query("SELECT * FROM menu_items ORDER BY path")->fetchAll();
    $tree = [];
    $pathMap = [];

    foreach ($items as $item) {
        $pathParts = explode('/', $item['path']);
        $parent = &$tree;

        foreach (array_slice($pathParts, 0, -1) as $part) {
            $parent = &$parent['children'][$part];
        }

        $parent['children'][$item['id']] = $item;
        $pathMap[$item['path']] = &$parent['children'][$item['id']];
    }

    return $tree;
}

前端展示

使用HTML和CSS展示树形结构:

function renderMenu($tree, $level = 0) {
    echo '<ul class="tree level-'.$level.'">';
    foreach ($tree as $node) {
        echo '<li>';
        echo htmlspecialchars($node['name']);
        if (!empty($node['children'])) {
            renderMenu($node['children'], $level + 1);
        }
        echo '</li>';
    }
    echo '</ul>';
}

// CSS样式示例
.tree ul {
    list-style: none;
    padding-left: 20px;
}
.tree li {
    position: relative;
    margin: 5px 0;
}

使用预排序遍历树算法(MPTT)

结合嵌套集模型的优化算法:

class MPTT {
    private $pdo;
    private $left = 'lft';
    private $right = 'rgt';

    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }

    public function rebuildTree($parent = 0, $left = 1) {
        $right = $left + 1;

        $stmt = $this->pdo->prepare("SELECT id FROM menu_items WHERE parent_id = ?");
        $stmt->execute([$parent]);

        while ($row = $stmt->fetch()) {
            $right = $this->rebuildTree($row['id'], $right);
        }

        $this->pdo->prepare("UPDATE menu_items SET lft = ?, rgt = ? WHERE id = ?")
            ->execute([$left, $right, $parent]);

        return $right + 1;
    }
}

使用第三方库

可以考虑使用现有的PHP库来简化实现:

  1. baum/baum: Laravel的嵌套集实现
  2. nicmart/tree: 通用的树结构库
  3. doctrine-extensions: 包含树形结构扩展

示例使用baum/baum:

php树形菜单的实现

// 在Laravel中安装后
class Category extends Baum\Node {
    protected $table = 'categories';
}

// 使用
$root = Category::create(['name' => 'Root']);
$child = Category::create(['name' => 'Child']);
$child->makeChildOf($root);

以上方法各有优缺点,邻接列表简单但查询效率低,嵌套集查询高效但维护复杂,路径枚举直观但更新困难。应根据项目需求选择合适的方法。

标签: 菜单php
分享给朋友:

相关文章

php 实现自动收货

php 实现自动收货

PHP 实现自动收货功能 自动收货功能通常用于电商系统,在订单超过一定时间未手动确认收货时自动完成订单。以下是实现方法: 数据库设计 需要订单表包含以下关键字段: CREATE TABLE…

php长连接实现

php长连接实现

PHP 长连接实现方法 长连接(Keep-Alive)允许客户端与服务器在一次TCP连接中发送和接收多个HTTP请求/响应,减少重复建立连接的开销。以下是PHP中实现长连接的几种方式: 配置HTTP…

php 实现文件下载

php 实现文件下载

实现文件下载的基本方法 使用 PHP 实现文件下载的核心是通过设置 HTTP 头部信息,强制浏览器将文件作为附件下载而非直接显示。以下是一个基础实现示例: $file_path = '/path/t…

php搜索功能实现的

php搜索功能实现的

PHP 搜索功能实现方法 数据库搜索实现 使用 SQL 的 LIKE 语句进行模糊匹配,适用于小型网站和简单搜索需求。 $searchTerm = $_GET['search']; $query =…

vue实现导航菜单

vue实现导航菜单

Vue 实现导航菜单的方法 使用 Vue Router 实现基本导航 在 Vue 项目中安装 vue-router,通过路由配置实现页面跳转。路由配置文件中定义路径和组件映射,导航菜单通过 <r…

php数据库实现

php数据库实现

PHP 连接 MySQL 数据库 使用 mysqli 扩展连接 MySQL 数据库: <?php $servername = "localhost"; $username = "usernam…