PHP系统左侧菜单栏的管理与实现
在日常的开发工作中,面对后台的日益增长的业务,以及后期业务的迭代开发,通常会选择添加菜单栏的形式来扩充业务功能,同样日益增长的后台菜单选项也为我们后期的维护,产生了一定的困难性。为此我总结出自己关于左侧菜单栏的管理模式或者方法。仅供参考。
在通常的开发中,对菜单栏的生成一般是通过以下几种方式:
(1)模板文件对变量的遍历(接下来以thinkPHP5为例)
(2)直接通过PHP进行组装
关于(2)直接通过PHP进行组装,不建议这样做,这样做会增大PHP代码与HTML的耦合与黏连,不利于代码的友好性。接下来着重讲解(1)模板文件对变量进行遍历在一般情况下,我们再设计或者制作后台的菜单栏的时候,一般会选择ul标签和li标签进行组合,以及进行样式的设置。来达到菜单的一般性要求,纵观菜单的制作与设计,菜单栏和列表数据项具有以下几个特点:
(1)通用性 适应不同屏幕的大小(暂时先不讨论响应式布局),在不同的浏览器要显示出相同的效果。
(2)扩展性 在实际的项目中,业务功能不会只有一个或者两个,会有很多。后期的迭代开发,新业务功能的添加会,都会用到列表项的扩展。
接下来继续讨论具备以上两种特征的菜单的管理的实现。
1.写入配置文件
顾名思义,将自己的菜单栏的所有信息,写入配置文件。
以thinkPHP5为例,只讲实现的思想不讲具体的代码。
接下来看PHP配置文件该怎么写呢?
'nav_set'=>[
[ 'name'=>'用户管理',
'url' =>url('/admin/UserManager/getAllUser'),
'other'=>[url('/admin/UserManager/getUserDetail')],
'icon'=>'fa fa-user-md',
'style'=>'color: white',
'state'=>0,
'hasSub'=>0
],
[
'name'=>'开仓平仓',
'url' =>url('/admin/Warehouse/getAllWarehouse'),
'icon'=>'gi gi-airplane',
'style'=>'color: white',
'state'=>0,
'hasSub'=>0
],
[
'name'=>'盈利播报',
'url' =>url('/admin/ProfitBroadcast/profitBroad'),
'icon'=>'fa fa-bullhorn',
'style'=>'color: white',
'state'=>0,
'hasSub'=>0
],
[
'name'=>'产品管理',
'url' =>url('/admin/Product/getAllProduct'),
'icon'=>'fa fa-product-hunt',
'style'=>'color: white',
'state'=>0,
'hasSub'=>0
],
[
'name'=>'所有订单',
'url' =>url('/admin/Product/getAllProduct'),
'icon'=>'fa fa-gavel',
'style'=>'color: white',
'state'=>0,
'hasSub'=>0
],
[
'name'=>'财务管理',
'url' =>url('/admin/Finance/financeInfo'),
'icon'=>'fa fa-money',
'style'=>'color: white',
'state'=>0,
'hasSub'=>0
],
[
'name'=>'编辑规则',
'url' =>url('/admin/EditRule/edit'),
'icon'=>'fa fa-pencil-square-o',
'style'=>'color: white',
'state'=>0,
'hasSub'=>0
], [
'name'=>'系统设置',
'icon'=>'fa fa-gear',
'style'=>'color: white',
'state'=>0,
'hasSub'=>1,
'sub'=>[
[
'name'=>'提成设置',
'url' =>url('/admin/SystemSetting/commission'),
'icon'=>'',
'style'=>'color: white',
'state'=>0,
],
[
'name'=>'金额设置',
'url' =>url('/admin/SystemSetting/money'),
'icon'=>'',
'style'=>'color: white',
'state'=>0,
],
]
],
[
'name'=>'账号设置',
'url' =>url('/admin/AccountSetting/index'),
'icon'=>'gi gi-user',
'style'=>'color: white',
'state'=>0,
'hasSub'=>0
],
]
有代码可以看出,在配置文件里面写入的是一个数组,里面包含的字段:state表示开关,name表示列表项的具体名称;url表示一个列表项的所链接的地址;style表示列表项特有的样式,hasSub表示是否有子列表。如果有需要还可以里面继续添加自己想要的字段。因此我们需要建立一个所有业务的控制器的父控制器Base,在Base的构造方法里面进行,列表的数据的获取与添加。Base控制器代码
class Base extends Controller
{
public function __construct(Request $request = null)
{
parent::__construct($request); $clicked_url = \request()->url(); //获取每次点击的url
$nav_arr = Config::get('nav_set'); //获取导航配置信息
$nav_arr = getMenu($nav_arr,$clicked_url); //对每个配置项进行状态设置 $this->assign('clicked_url',$clicked_url); //对页面进行赋值
$this->assign('nav_list',$nav_arr); }
}
里面有一个核心的算法:getMenu($nav_arr,$clicked_url)请看具体代码的实现
/**
* 将所点击的列表项以及其父列表项的state置1
*
* @param $menu_arr 菜单栏配置信息
* @param $url 点击的链接
* @return array|bool
*/
function getMenu($menu_arr,$url){ if (!is_array($menu_arr)){
return false;
} for ($i = 0;$i < count($menu_arr);$i++){
if (array_key_exists('url',$menu_arr[$i]) && !empty($menu_arr[$i]['url'])){
$menu_url = strtolower($menu_arr[$i]['url']);
$url = strtolower($url);
$menu_url = explode('.',$menu_url)[0];
$url = explode('.',$url)[0]; // 比对点击的url和配置信息中的url是否一致
if (strpos($menu_url,$url) !== false){
$menu_arr[$i]['state'] = 1;
return $menu_arr;
}else{
// 多个url绑定到一个列表项
if (array_key_exists('other',$menu_arr[$i]) && !empty($menu_arr[$i]['other'])){
for ($j = 0;$j < count($menu_arr[$i]['other']);$j++){
$other_url = $menu_arr[$i]['other'][$j];
$other_url = explode(',',strtolower($other_url))[0];
if (strpos($other_url,$url) !== false){ $menu_arr[$i]['state'] = 1;
return $menu_arr;
}
}
}
}
}else{
if (array_key_exists('sub',$menu_arr[$i])){
// 继续进行递归搜索
$sub = getMenu($menu_arr[$i]['sub'],$url); if ($sub == $menu_arr[$i]['sub']){
$menu_arr[$i]['state']=0;
}else{
$menu_arr[$i]['state']=1;
} $menu_arr[$i]['sub'] = $sub;
}
}
} return $menu_arr;
}
getMenu()这个方法主要进行配置数组的处理,为了增加其扩展性,采用了递归的方式进行处理的。
接下请看模板文件的代码:
<ul class="sidebar-nav" style="color: white;font-size: 17px;">
<volist name="nav_list" id="bar">
<li>
<if condition="$bar.hasSub == 1">
<if condition="$bar.state == 1">
<a href="#" class="sidebar-nav-menu open" style="color: white">
<i class="fa fa-chevron-left sidebar-nav-indicator sidebar-nav-mini-hide"></i>
<i class="fa fa-gear sidebar-nav-icon"></i>
<span class="sidebar-nav-mini-hide">{$bar.name}</span>
</a>
<else/>
<a href="#" class="sidebar-nav-menu" style="color: white">
<i class="fa fa-chevron-left sidebar-nav-indicator sidebar-nav-mini-hide"></i>
<i class="fa fa-gear sidebar-nav-icon"></i>
<span class="sidebar-nav-mini-hide">{$bar.name}</span>
</a>
</if> <ul>
<volist name="$bar.sub" id="sub_bar"> <li>
<if condition="$sub_bar.state == 1">
<a href="{$sub_bar.url}" class="active">{$sub_bar.name}</a>
<else/>
<a href="{$sub_bar.url}" class="" style="color: white">{$sub_bar.name}</a>
</if>
</li>
</volist>
</ul> <else/>
<if condition="$bar.state == 1">
<a href="{$bar.url}" class="open" style="{$bar.style}">
<i class="{$bar.icon} sidebar-nav-icon"></i>
<span>{$bar.name}</span>
</a>
<else/> <a href="{$bar.url}" style="{$bar.style}">
<i class="{$bar.icon} sidebar-nav-icon"></i>
<span>{$bar.name}</span>
</a>
</if> </if>
</li>
</volist>
</ul>
在模板文件内循环加入我们所设置的信息,最终效果如下图
2.写入数据库
关于写入数据库方式,通常不是用来作为功能菜单了,类似淘宝、京东首页左侧商品列表,为此我们需要建立相关的表来存放这些商品和商品的类别,并且还要考虑后期的扩展,假如双十一或者618他们的列表项是不一样的。本次我么只讨论功能性列表的管理,对此不再赘述。
更过的进阶技术可以关注公众号:进阶的脚步 回复:学习资料 有惊喜哦
PHP系统左侧菜单栏的管理与实现的更多相关文章
- PHP左侧菜单栏的管理与实现
以thinkPHP5.0为例 后台config.php文件里配置 //配置文件设置菜单内容属性 'menu' => [ [ 'name' => '菜单栏1', 'url' => '/ ...
- linux系统用户以及用户组管理
本系列的博客来自于:http://www.92csz.com/study/linux/ 在此,感谢原作者提供的入门知识 这个系列的博客的目的在于将比较常用的liunx命令从作者的文章中摘录下来,供自己 ...
- Visio 2007/2010 左侧"形状"窗口管理
Visio 2007/2010 左侧"形状"窗口管理 Visio 打开后,通常窗口左侧会有一个“形状”面板,我们可以方便地从中选择需要的形状.有时为了获得更大的版面空间或者不小心关 ...
- linux入门教程(七) linux系统用户以及用户组管理
关于这部分内容,笔者在日常的linux系统管理工作中用到的并不多,但这并不代表该内容不重要.毕竟linux系统是一个多用户的系统,每个账号都干什么用,你必须了如指掌.因为这涉及到一个安全的问题. [认 ...
- WebStorm设置左侧菜单栏背景和字体设置
WebStorm左侧菜单栏 webstorm是一款前端IDE利器,个人感觉黑色的背景比较炫酷,刚开始从网上下载的主题只能修改编辑窗口的背景色,经过查询资料终于把左边菜单栏的背景色也修改了. 第一步:点 ...
- 纳税服务系统【信息发布管理、Ueditor、异步信息交互】
需求分析 我们现在来到了纳税服务系统的信息发布管理模块,首先我们跟着原型图来进行需求分析把: 一些普通的CRUD,值得一做的就是状态之间的切换了.停用和发布切换. 值得注意的是:在信息内容中,它可以带 ...
- WPF仿网易云音乐系列(一、左侧菜单栏:Expander+RadioButton)
1.简介 上一篇咱们说到,网易云音乐的左侧菜单栏可以通过Expander+RadioButton来实现,具体如何实现,咱们下面开始干: 首先来一张网易云音乐PC版原图(个人觉得PC版比UWP版左侧菜单 ...
- 系统批量运维管理器Fabric详解
系统批量运维管理器Fabric详解 Fabrici 是基于python现实的SSH命令行工具,简化了SSH的应用程序部署及系统管理任务,它提供了系统基础的操作组件,可以实现本地或远程shell命令,包 ...
- Linux学习总结(十六)系统用户及用户组管理
先来认识两个文件 /etc/passwd/etc/shadow我们打印出首尾三行,来了解下:每行由:分割为7段,每段含义为:第一段:用户名,比如root 用户,普通用户test,lv,test1第二段 ...
随机推荐
- 从#65279字符看dede模板页面编码问题
今天一位朋友让帮忙给解决一个dede模板的问题,问题主要是:模板文件生成html文件之后会在body开头处加入一个可见的控制符,导致页面头部会出现一个空白行. 接到"& ...
- Java Enum解析【转】
Enum用法: 1:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多 ...
- [知了堂学习笔记]_集合接口list与集合接口set的区别
在Java中 除了 Map以外的集合的根接口都是Collection接口,而在Collection接口的子接口中,最重要的莫过于List和Set集合接口. 今天我们就来谈谈List集合接口与Set集合 ...
- 前端css常用class命名id命名
1.常用id的命名: (1)页面结构 容器: container 页头:header 内容:content/container 页面主体:main 页尾:footer 导航:nav 侧栏:sideba ...
- Linux 性能搜集【top/vmstat/iostat】
为方便问题发生后,问题原因的分析排查,我们可以在服务器中事先部署如下脚本,方便故障发生后,问题原因的分析排查 脚本部署方法: 1.将脚本[top_monitor.sh]上传到服务器 2.登陆虚拟机,并 ...
- string用法总结
要想使用标准C++中的string类,必须要包含#include <string> 注意是<string>而不是<string.h>,带.h的是C语言中的头文件 s ...
- 关系类型字段 -- Django从入门到精通系列教程
该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...
- 用户 'IIS APPPOOL\.NET v4.5 Classic' 登录失败。
我在win8.1系统下用vs2013+SqlServer08编写完项目后,挪到另一台win8.1系统(安装了Vs2010+SqlServer08)中,把网址挂到IIs中时,出现如下错误 : 解决方案: ...
- linux 搭建PPTP
pptp简介 PPTP,Point to Point Tunneling Protocol,点对点隧道协议,这是一种支持多协议虚拟专用网络(VPN)技术.远程用户能够通过装有点对点协议的系统安全访问公 ...
- debug时ClassNotFound可能出现的原因
自我总结,欢迎拍砖! 目的:总结ClassNotFound可能出现的原因,方便以后定位该类问题. 原因:当项目中加了新类,debug或run时,报classnotfound,说明没有找到该类的clas ...