tp5框架前臺無限極導航菜單類實現(xiàn)方法分析
本文實例講述了tp5框架前臺無限極導航菜單類實現(xiàn)方法。分享給大家供大家參考,具體如下:
適用于 id name pid sort 類似結(jié)構(gòu)的表結(jié)構(gòu)
使用方法:(tp5)
1、將最下面的代碼保存到“前臺”控制器目錄下(名為 FrontNav.php),比如(路徑): application/index/controll(應用/模塊/控制器)
2、在控制器中使用:(application/index/controll/index)(應用/模塊/控制器/方法)
也可以放到基礎類的初始化方法中,如:Base.php 的 _initialize() 方法(不用多解釋,這個是 tp5 的初始化方法 貌似 init() 也行?可以自己試試)
使用:
1)、第一步:先實例化本類, 5 個參數(shù)。
參數(shù)說明:
- param 1:必填 字符串類型 數(shù)據(jù)表名稱(也是模型名稱),不用其實字母大寫也行。例如: category
- param 2:選填 字符串類型 模型所在的路徑(默認是:admin模塊下的model目錄)。如果你不叫 admin,那么書寫格式如下:houtai/model
- param 3:必填 字符串類型 父級欄目字段名稱,例如:pid(parent id)
- param 4:選填 數(shù)組類型 默認是按 id 正序排序的,如果有排序字段 sortField 的值為 字段名稱 如 sort 或者 listorder 等…,sortOrder 的值為 asc(正序) 或 desc (倒序),建議按這個排序,要不然會顯示有點亂,因為權重的關系需要手動排序顯示的位置。
- param 5:必填 二維數(shù)組 替換關鍵詞,該參數(shù)的第一個數(shù)組為頂部導航所需要替換的關鍵詞(必填),linkUrl(url 鏈接)是固定模式,必須這么寫,它的值是:模塊/控制器/方法,其他的鍵為要替換的關鍵詞值為字段名稱。第二個數(shù)組(選填)為二級菜單,第三個數(shù)組(選填)為N級菜單,此三個數(shù)組個數(shù)要對應 $this->createNavHtml() 方法中模版參數(shù)的個數(shù),詳見 createNavHtml() 方法解釋。
$frontNav = new FrontNav('category', '', 'pid', array( 'sortField' => 'sort', 'sortOrder' => 'asc' ), array( array( 'linkUrl' => 'index/artlist/index', 'catName' => 'name', 'catDesc' => 'desc' ), array( 'linkUrl' => 'index/artlist/index', 'catName' => 'name', 'catDesc' => 'desc' ) ));
2)、第二步:生成 導航的 html 結(jié)構(gòu),4個參數(shù)
- param 1:選填 字符串類型 首頁的 html 模版,例如 ‘<li><a class=”navi_home” href=”/”>首頁</a></li>'
- param 2:必填 數(shù)組類型 頂部導航的 html 模版,注意下面實例的格式寫法
- param 3:選填 數(shù)組類型 二級菜單的 html 模版,同上
- param 4:選填 數(shù)組類型 N級菜單的 html 模版,同上
$navHtml = $frontNav->createNavHtml('<li><a class="navi_home" href="/" rel="external nofollow" rel="external nofollow" >首頁</a></li>', array( '<ul id="jsddm" class="topNav">', '<li><a href="linkUrl" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="catDesc">catName</a>', '</li>', '</ul>' ), array( '<ul class="twoLevel">', '<li><a href="linkUrl" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="catDesc">catName</a>', '</li>', '</ul>' ), '');
3)、第三步:向模版輸出
$this->assign(array( 'navHtml' => $navHtml ));
4)、第四步:模版調(diào)用(多余??)
<div id="navi"> {$navHtml} </div>
提示:
1、替換關鍵詞參數(shù)個數(shù)與模版(除了首頁外)參數(shù)個數(shù)一定要對應,打字解釋的可能有點不明白,詳細的對照 實例化 和 創(chuàng)鍵方法 的代碼看幾遍就明白了,實在不行可以看源程序,都有較詳細的注釋。
2、本類默認模型優(yōu)先,如果沒有模型就會查表返回數(shù)據(jù)庫實例。
3、還有一點要注意就是你的替換關鍵詞盡量要跟模版里的字符串不要重復,比如說,你的替換關鍵詞叫 ‘id' => catename,而模版里 <li id=”xixixi”><a href=”###”>哎呀?</a></li>,要是這樣就壞了…
求高手改成php原生的,可聯(lián)系qq發(fā)給我嗎?嘿嘿…
具體哪有不清楚的可以聯(lián)系我QQ
效果圖:(好像也支持無限極菜單)
<?php /** * Created by PhpStorm. * User: Chao Chao * Date: 2017/9/23 * Time: 10:18 * versions: 1.0.0 * url: null * email: 2776332953@qq.com * phone: *** */ namespace app\index\controller; use think\Db; // 引用 Db (數(shù)據(jù)庫鏈接) 類 use think\Url; // 引用 Url ( 創(chuàng)建 url) 類 use think\Loader; // 引用 Loader ( 加載 ) 類 class FrontNav { // 數(shù)據(jù)庫實例 protected $db; // 無限極字段名稱 protected $pidName = ''; // 排序設置 protected $sort = array(); // 一級導航html模版 protected $levelOne = array(); // 二級導航html模版 protected $levelTwo = array(); // n級導航html模版 protected $levelN = array(); // nav html protected $navHtml = ''; // 替換關鍵詞 protected $replaceKeywords = array(); /** * FrontNav constructor. 構(gòu)造方法用于生成數(shù)據(jù)實例與配置參數(shù) * @param string $name 數(shù)據(jù)表名稱或模型名稱 * @param string $modelPath 模型所在路徑,默認為 admin/model (admin模塊下的model目錄) * @param string $pidName 無限極分類的字段(如:pid 或 parentid 等) * @param string $sort 要排序的字段名稱 * @param array $replaceKeywords 定義的替換關鍵詞 */ public function __construct($name, $modelPath, $pidName, $sort, $replaceKeywords) { // $name 為必填參數(shù) if (empty($name) || !is_string($name)) { throw new \think\Exception('參數(shù)錯誤 $name(表名稱或模型名稱),實例化時該參數(shù)必須為字符串類型且不能為空!'); } // 模型優(yōu)先考慮 如果 模型類先存在 就返回 模型實例,否則返回 Db 類實例。 // 防止大小寫錯誤,先都轉(zhuǎn)換成小寫在將第一個字母大寫 如:Category,因為 linux 區(qū)分大小寫 $fileName = ucwords(strtolower($name)); // 一般欄目的模型都在后臺,所以這里就寫死了地址 '/admin/model/',也可以傳參制定位置 $modelPath = !empty($modelPath) ? strtolower($modelPath) : 'admin/model'; if (class_exists('app\\' . str_replace('/', '\\', $modelPath) . '\\' . $fileName)) { $this->db = Loader::model($fileName, 'model', false, 'admin'); } else { // 不確定在 linux 下數(shù)據(jù)庫名稱是否區(qū)分大小寫,所以都轉(zhuǎn)換成小寫。 $this->db = Db::name(strtolower($fileName)); } // 無限極父類字段不能為空 if (!empty($pidName)) { $this->pidName = $pidName; } else { throw new \think\Exception('參數(shù)錯誤 $pidName(父欄目id),實例化時字段名稱不能為空!'); } // 替換關鍵詞 if (empty($replaceKeywords) || !is_array($replaceKeywords)) { throw new \think\Exception('參數(shù)錯誤 $replaceKeywords(替換關鍵詞),實例化時該參數(shù)必須是而為數(shù)組類型且不能為空!');; } else { $this->replaceKeywords = $replaceKeywords; } $this->sort = $sort; } /** * 控制器調(diào)用,生成導航菜單。頂層導航的樣式( 參數(shù)2 $levelOneTemplate )為必填項,也就是說最基本的是一層導航,二級和多級是選填項( 參數(shù)3: $levelTwoTemplate 與 參數(shù)4 $levelNTemplate 非必填項 ) * @param string $homePageHml 首頁 標簽的html樣式,如: <li><a class="navi_home" href="/" rel="external nofollow" rel="external nofollow" >首頁</a></li> * @param array $levelOneTemplate 必填 頂部導航的html樣式,如: array( * '<ul id="jsddm" class="topNav">', 最外層 ul * '<li><a href="linkUrl" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="catDesc">catName</a>', li標簽 * '</li>', li 結(jié)束 * '</ul>' ul 結(jié)束 * ) * @param array $levelTwoTemplate 選填 二級菜單的html樣式,如: array( * '<ul class="twoLevel">', 二級菜單的 ul * '<li><a href="linkUrl" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="catDesc">catName</a>', li標簽 * '</li>',li 結(jié)束 * '</ul>'ul 結(jié)束 * ) * @param array $levelNTemplate 選填 多級菜單的html樣式,如: array( * '<ul class="nLevel">', N級菜單的 ul * '<li><a href="linkUrl" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="catDesc">catName</a>', li標簽 * '</li>',li 結(jié)束 * '</ul>'ul 結(jié)束 * @return string */ public function createNavHtml($homePageHml, $levelOneTemplate, $levelTwoTemplate, $levelNTemplate) { // 第一層導航不能為空且必須是數(shù)組 if (empty($levelOneTemplate) || !is_array($levelOneTemplate)) { throw new \think\Exception('參數(shù)錯誤 $levelOneTemplate(一級導航模版),該參數(shù)必須是數(shù)組類型且不能為空!'); } $this->levelOne = $levelOneTemplate; // 二級導航 if (!empty($levelTwoTemplate) && !is_array($levelTwoTemplate)) { throw new \think\Exception('參數(shù)錯誤 $levelTwoTemplate(二級導航模版),該參數(shù)可以為空 \'\' 或 array(),否則必須是數(shù)組類型!'); } $this->levelTwo = $levelTwoTemplate; // N級導航 if (!empty($levelNTemplate) && !is_array($levelNTemplate)) { throw new \think\Exception('參數(shù)錯誤 $levelNTemplate(N級導航模版),該參數(shù)可以為空 \'\' 或 array(),否則必須是數(shù)組類型!'); } $this->levelN = $levelNTemplate; $treeData = $this->getTreeData($this->getAllData(), 0); //print_r($treeData); $this->createHtml($treeData); return $this->levelOne[0] . (!empty($homePageHml) ? $homePageHml : '') . $this->navHtml . $this->levelOne[3] . "\n"; } /** * 獲取所有數(shù)據(jù) * @return array */ private function getAllData() { if (empty($this->sort) || empty($this->sort['sortField']) || empty($this->sort['sortOrder'])) { return collection($this->db->where(1) ->select())->toArray(); } else { return collection($this->db->where(1) ->order($this->sort['sortField'] . ' ' . $this->sort['sortOrder']) ->select())->toArray(); } } /** * 將所有數(shù)據(jù)攢成樹狀結(jié)構(gòu)的數(shù)組 * 增加 levels (層級) children (子數(shù)組) * @param $allData 傳遞過來的所有非樹狀結(jié)構(gòu)的數(shù)組 * @param $parentId 初始化時的父欄目id * @return array 樹狀結(jié)構(gòu)的數(shù)組 */ private function getTreeData($allData, $parentId) { $tree = array(); // 層級計數(shù) static $number = 1; foreach ($allData as $v) { if ($v[$this->pidName] == $parentId) { if ($v[$this->pidName] == 0) { $v['levels'] = 0; } else { $v['levels'] = $number; ++$number; } $v['children'] = $this->getTreeData($allData, $v['id']); $tree[] = $v; } else { $number = 1; } } return $tree; } /** * 遞歸生成樹狀結(jié)構(gòu)的html * @param $allData array 由 createNavHtml() 方法傳遞過來的 樹形結(jié)構(gòu) 數(shù)據(jù)(數(shù)組) * @return string 返回(最外層ul內(nèi)部的html)樹狀結(jié)構(gòu)的html */ private function createHtml($allData) { foreach ($allData as $v) { // 頂部導航 if ($v['levels'] == 0) { $tempStr0 = $this->levelOne[1]; foreach ($this->replaceKeywords[0] as $k1 => $v1) { if ($k1 == 'linkUrl') { $tempStr0 = str_replace($k1, Url::build($v1, 'id=' . $v['id']), "\n" . $tempStr0); } else { $tempStr0 = str_replace($k1, $v[$v1], $tempStr0); } } $this->navHtml .= $tempStr0; if (empty($v['children'])) { $this->navHtml .= $this->levelOne[2] . "\n"; } else if (!empty($v['children']) && !empty($this->levelTwo)) { $this->navHtml .= "\n" . $this->levelTwo[0] . "\n"; $this->createHtml($v['children']); $this->navHtml .= $this->levelTwo[3] . $this->levelOne[2]; } } // 二級菜單 if ($v['levels'] == 1) { $tempStr2 = $this->levelTwo[1]; foreach ($this->replaceKeywords[1] as $k1 => $v1) { if ($k1 == 'linkUrl') { $tempStr2 = str_replace($k1, Url::build($v1, 'id=' . $v['id']), $tempStr2); } else { $tempStr2 = str_replace($k1, $v[$v1], $tempStr2); } } $this->navHtml .= $tempStr2; if (empty($v['children'])) { $this->navHtml .= $this->levelTwo[2] . "\n"; } else if (!empty($v['children']) && !empty($this->levelN)) { // 是否多級導航,有 children ,還必須有3級 html 模版 $this->navHtml .= "\n" . $this->levelN[0] . "\n"; $this->createHtml($v['children']); $this->navHtml .= $this->levelN[3] . $this->levelTwo[2] . "\n"; } } // 多級菜單 if (!empty($this->levelN) && $v['levels'] > 1) { $tempStrN = $this->levelN[1]; foreach ($this->replaceKeywords[2] as $k1 => $v1) { if ($k1 == 'linkUrl') { $tempStrN = str_replace($k1, Url::build($v1, 'id=' . $v['id']), $tempStrN); } else { $tempStrN = str_replace($k1, $v[$v1], $tempStrN); } } $this->navHtml .= $tempStrN; if (empty($v['children'])) { $this->navHtml .= $this->levelN[2] . "\n"; } else { $this->navHtml .= $this->levelN[0]; $this->createHtml($v['children']); $this->navHtml .= $this->levelN[3] . $this->levelN[2]; } } } return $this->navHtml; } }
更多關于thinkPHP相關內(nèi)容感興趣的讀者可查看本站專題:《ThinkPHP入門教程》、《thinkPHP模板操作技巧總結(jié)》、《ThinkPHP常用方法總結(jié)》、《codeigniter入門教程》、《CI(CodeIgniter)框架進階教程》、《Zend FrameWork框架入門教程》及《PHP模板技術總結(jié)》。
希望本文所述對大家基于ThinkPHP框架的PHP程序設計有所幫助。
- thinkphp實現(xiàn)面包屑導航(當前位置)例子分享
- ThinkPHP+EasyUI之ComboTree中的會計科目樹形菜單實現(xiàn)方法
- thinkPHP實現(xiàn)的聯(lián)動菜單功能詳解
- thinkPHP基于ajax實現(xiàn)的菜單與分頁示例
- ThinkPHP使用心得分享-ThinkPHP + Ajax 實現(xiàn)2級聯(lián)動下拉菜單
- ThinkPHP無限級分類原理實現(xiàn)留言與回復功能實例
- thinkphp實現(xiàn)無限分類(使用遞歸)
- ThinkPHP自動填充實現(xiàn)無限級分類的方法
- ThinkPHP實現(xiàn)遞歸無級分類——代碼少
- 使用ThinkPHP的自動完成實現(xiàn)無限級分類實例詳解
相關文章
PHP 實現(xiàn)從數(shù)據(jù)庫導出到.csv文件方法
這篇文章主要介紹了 PHP 實現(xiàn)從數(shù)據(jù)庫導出到.csv文件方法的相關資料,需要的朋友可以參考下2017-07-07詳解php中serialize()和unserialize()函數(shù)
這篇文章主要介紹了php的serialize()函數(shù)和unserialize()函數(shù)的相關資料,需要的朋友可以參考下2017-07-07php 反斜杠處理函數(shù)addslashes()和stripslashes()實例詳解
PHP自帶的庫函數(shù) addslashes() 和 stripslashes() 都屬于字符串處理類函數(shù), 本文章向大家介紹php 反斜杠處理函數(shù)addslashes()和stripslashes(),需要的朋友可以參考下2016-12-12php使用strtotime和date函數(shù)判斷日期是否有效代碼分享
php使用strtotime和date函數(shù)進行檢驗判斷日期是否有效代碼分享,大家參考使用吧2013-12-12