1. 程式人生 > >PHP系統左側菜單欄的管理與實現

PHP系統左側菜單欄的管理與實現

ini 適應 xtend name 數組 mage for fun fig

在日常的開發工作中,面對後臺的日益增長的業務,以及後期業務的叠代開發,通常會選擇添加菜單欄的形式來擴充業務功能,同樣日益增長的後臺菜單選項也為我們後期的維護,產生了一定的困難性。為此我總結出自己關於左側菜單欄的管理模式或者方法。僅供參考。

在通常的開發中,對菜單欄的生成一般是通過以下幾種方式:

(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系統左側菜單欄的管理與實現