首先创建数据库:
CREATE DATABASE IF NOT EXISTS `fenlei` DEFAULT character SET utf8 COLLATE utf8_general_ci;
USE `fenlei`;
CREATE TABLE IF NOT EXISTS `category` (
`catid` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`upid` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '上级分类catid',
`catname` varchar(255) NOT NULL DEFAULT '' COMMENT '分类名称',
`displayorder` tinyint(1) NOT NULL DEFAULT '0' COMMENT '显示顺序',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-关闭,1-启用',
PRIMARY KEY (`catid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='文章分类';
INSERT INTO `category` VALUES
('1', '0', '分类1', '0', '1'),
('2', '0', '分类2', '0', '1'),
('3', '0', '分类3', '0', '1'),
('4', '0', '分类4', '0', '1'),
('5', '0', '分类5', '0', '1'),
('6', '1', '分类1-1', '0', '1'),
('7', '1', '分类1-2', '0', '1'),
('8', '1', '分类1-3', '0', '1'),
('9', '1', '分类1-4', '0', '1'),
('10', '1', '分类1-5', '0', '1'),
('11', '6', '分类1-1-1', '0', '1'),
('12', '6', '分类1-1-2', '0', '1'),
('13', '6', '分类1-1-3', '0', '1'),
('14', '7', '分类1-2-1', '0', '1'),
('15', '7', '分类1-2-2', '0', '1'),
('16', '11', '分类1-1-1-1', '0', '1'),
('17', '11', '分类1-1-1-2', '0', '1');
model
/*
* 这是一个成熟的模型,放入相应文件夹直接调用即可
*/
namespace app\index\model;
class Category extends \think\Model
{
/*
* 打开冰箱:从数据库取出所有数据,并放进缓存内
* 即可独立输出也可以在其他位置调用
*/
public function category_query($catid=0)
{
cache('category',null);//正式环境删除本行可减少一次查询
if(!$result = cache('category')){
$Category = new Category();
$result = [];
foreach($Category->order('displayorder asc,catid asc')->select() as $data){
$result[$data['catid']] = $data;
}
cache('category',$result,0);
}
return $catid ? $result[$catid] : $result;//如果传入单个分类catid,那么直接返回就行,可用于列表页,大大降低查询次数
}
/*
* 把大象放进冰箱:将第一步得到的数据集转化为无限级数组
* 即可独立输出也可以在其他位置调用
*/
public function category_tree($upid=0,$status='0,1'){
$status = is_string($status) ? explode(',', $status) : $status;
$result = [];
foreach($this->category_query() as $catid=>$cat){
if($upid == $cat['upid'] && in_array($cat['status'],$status)){
$cat['subcat'] = $this->category_tree($cat['catid'],$status);
$result[] = $cat;
}
}
return $result;
}
/*
* 关上冰箱门:用于实际用途,将多级数据传入,转化为前端html代码
* 该html的转化结果可从第一步中获取方式不同来实现从哪一级开始展示
* 本函数只是师范函数,实际运用中只需要修改这个函数结构体就能完全实现仿网易盖楼效果
*/
public function category_html($categorys,$depth=0){
$depth_html = $html = '';
for ($i=0; $i < $depth; $i++) {
$depth_html .= '——';
}
foreach($categorys as $data){
$html .= '
';$html .= '
'.$data['catid'].'';$html .= '
'.$data['displayorder'].'';$html .= '
'.$depth_html.$data['catname'].'';$html .= '
';if($data['subcat']){
$html .= $this->category_html($data['subcat'],$depth+1);
}
}
return $html;
}
}
?>
首先通过category_query方法获取到所有分类,
然后通过category_tree方法将得到的数据转化为无限分类数组
最后再通过category_html方法将上面得到的无限分类数组输出为html
控制器Controller
namespace app\index\controller;
use think\Controller;
use app\index\model\Category;//引入模型类
class Index extends Controller
{
public function index()
{
$Category = new Category;//实例化类
$category_tree = $Category->category_tree();// 获取整体多级数组树结果
$this->view->category_list = $Category->category_html($category_tree);//将结果转化为实体html并传值给模板
return $this->fetch();
}
}
来调用输出数据,最终结果如下: