php可以设计菜单吗,PHP 无限级菜单/权限树设计与实现

本文介绍了如何设计和实现动态菜单与权限树,通过在数据库中创建SuperUserMenus表,利用pid字段表示父子关系,实现无限级菜单。在ThinkPHP5框架下,先读取用户权限数据,然后使用array_column处理成索引数组,再通过gettreeitems函数将数据转换为树形结构。这种方法简化了数据在数据库中的查看,但需要额外的算法进行遍历和展示。
摘要由CSDN通过智能技术生成

在开发中我们经常会遇到:导航菜单、部门菜单、权限树、评论等功能。

这些功能都有共同的特点:

有父子关系

可无限递归

以导航菜单为例, 将导航菜单设置为动态的, 即从动态加载菜单数据。

数据库设计

CREATE TABLE `SuperUserMenus` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `pid` int(11) NOT NULL COMMENT '父级ID', `order` int(11) NOT NULL DEFAULT '0' COMMENT '菜单排序', `title` varchar(100) NOT NULL COMMENT '菜单标题', `controller` varchar(100) DEFAULT NULL COMMENT '控制器名称', `method` varchar(100) DEFAULT NULL COMMENT '方法名称', `ishidden` int(1) NOT NULL DEFAULT '0' COMMENT '是否隐藏:0正常显示,1隐藏', `status` int(1) NOT NULL DEFAULT '0' COMMENT '状态:0正常,1禁用', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8;

在这里用作分级的表示字段就是pid,用作查找对应父ID,一个菜单一方面自己可以具有父ID,可以有一个父级菜单,另一方面可以用作父级,子级来定义该父级ID,这样就可以设计无限级菜单,这样设计好处是可以父子级别菜单同表存储,便于遍历显示,但是存储在表中的数据只有对应逻辑,不好在数据库中维护及查看,需要写一下算法进行可视化遍历。

数据封装

array(8) { [0] => array(9) { ["id"] => int(1) ["pid"] => int(0) ["order"] => int(0) ["title"] => string(18) "超级用户管理" ["controller"] => string(0) "" ["method"] => string(0) "" ["ishidden"] => int(0) ["status"] => int(0) ["children"] => array(1) { [0] => array(8) { ["id"] => int(3) ["pid"] => int(1) ["order"] => int(0) ["title"] => string(18) "超级用户列表" ["controller"] => string(14) "admin" ["method"] => string(5) "index" ["ishidden"] => int(0) ["status"] => int(0) } } } }

算法转换

在这里使用ThinkPHP5这个框架来进行编写,虽然语言及框架不同,但是思路及使用算法函数都是一样的,首先将对应用户下菜单json存储数组读取出并进行索引处理:

/** * 动态菜单显示操作 * @return string */ public function index() { $Super_id = 1; $menus = false; $role = Db::table('SuperUser')->where('Super_id', $Super_id)->select(); $role = $role[0]; if ($role) { $role['rights'] = (isset($role['rights']) && $role['rights']) ? json_decode($role['rights'], true) : []; } if ($role['rights']) { $menus = Db::query('select * from SuperUserMenus where id in(' . implode(',', $role['rights']) . ') and ishidden=0 and status=0'); $menus = $this->_array_column($menus, null, 'id'); $menus && $menus = $this->gettreeitems($menus); } return json_encode($menus); }

之后将ID作为二维数组中的唯一索引,这里使用array_column函数,由于这个函数只支持PHP5.5+版本,低版本不支持,我将此函数放在此处:

/** * PHP5.5+ array_column函数 * @param null $input * @param null $columnKey * @param null $indexKey * @return array|bool|null */ public function _array_column($input = null, $columnKey = null, $indexKey = null) { // Using func_get_args() in order to check for proper number of // parameters and trigger errors exactly as the built-in array_column() // does in PHP 5.5. $argc = func_num_args(); $params = func_get_args(); if ($argc

最后将数组进行树形分类,将同属于一个父级ID的子元素归类至children下:

  /**   * 子节点分级显示   * @param $items   * @return array   */  private function gettreeitems($items)      {          $tree = array();          foreach ($items as $item) {              if (isset($items[$item['pid']])) {                  $items[$item['pid']]['children'][] = &$items[$item['id']];              } else {                  $tree[] = &$items[$item['id']];              }          }          return $tree;      }

无限级菜单/权限树设计原理就是使用pid来进行区分父子关系,就是将二维数组进行树形划分来实现。

-End-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值