无限极分类是指通过指定一个顶级分类,自动获取这个分类下的所以子孙级分类,直至取完这个顶级分类所包含的所有分类。这个功能在web网站中非常常见,比如jd,天猫,苏宁易购等商城的产品分类。
实现无限极分类的方法不唯一,今天这里就分享下通过php递归方法实现无限极分类。
先来看下分类的数据表
表中需要关注的字段catid:分类id,parentid:父级分类id,child:是否有子分类,(siteid这个字段不用关注),catname:分类名称,arrchildid:这个字段存放的是当前分类及其子分类的id,这里也用不到,实现无限极分类后可以用该字段来验证分类是否正确。
递归实现无限极分类的具体方法步骤:
实现无限极分类主要分为两大步:获取数据——输出数据。
1、获取数据:
<?php //在实际项目中可以通过类的方式来实现无线分类,把数据库连接资源句柄放到类的初始化中,避免在获取分类时重复连接数据库 try{ /** * 分类获取 */ function getCategorys($pid, $list = []){ //pdo资源句柄,在实际项目中不应该放在方法内 $pdo = new PDO('mysql:host=localhost;dbname=phpcmsv9hfzx', 'root', 'root'); $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); $sql = 'select * from v9_category where parentid=:parentid'; $stmt = $pdo->prepare($sql); $pid = intval($pid); $stmt->bindParam(':parentid', $pid); $stmt->execute(); $res = $stmt->fetchAll(PDO::FETCH_ASSOC); //遍历取出的数据,如果有子分类则通过递归继续取下级分类数据 foreach ($res as $key => $value) { $childList = []; if($value['child']){ $childList = getCategorys($value['catid']); } $list[] = [ 'catid' => $value['catid'], 'catname' => $value['catname'], 'child' => $value['child'], 'childList' => $childList ]; } return $list; } }catch(PDOException $e){ echo $e->getMessage(); }
递归获取分类数据:
首先取出指定顶级分类下的分类,然后遍历其分类并判断其是否还有下级分类,如果有继续取出分类数据,然后再次遍历去除的下级分类...取分类-遍历判断是一个往复的过程,因此可以使用递归来实现。每次遍历完之后把数据返回出去,外层接收返回数据,并放到其子分类下。
之所以采用这种方式,是为了让父级分类和子级分类有个明显的层次关系,让我们取出来的数据即使不输出也可以一目了然,而且有时可能只要父级分类不需要子级分类,在输出父级分类的时候直接跳过子级分类判断即可。
2、数据输出
<?php try{ /** * 分类获取 */ function getCategorys($pid, $list = []){ $pdo = new PDO('mysql:host=localhost;dbname=phpcmsv9hfzx', 'root', 'root'); $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); $sql = 'select * from v9_category where parentid=:parentid'; $stmt = $pdo->prepare($sql); $pid = intval($pid); $stmt->bindParam(':parentid', $pid); $stmt->execute(); $res = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($res as $key => $value) { $childList = []; if($value['child']){ $childList = getCategorys($value['catid']); } $list[] = [ 'catid' => $value['catid'], 'catname' => $value['catname'], 'child' => $value['child'], 'childList' => $childList ]; } return $list; } /** * 分类遍历 */ function nav($list, &$str=''){ $str.='<ul class="list">'; foreach ($list as $key => $value) { $str.= '<li>'.$value['catname']; //判断是否有子级分类且子级分类是否不为空 if($value['child'] && !empty($value['childList'])){ nav($value['childList'], $str); } $str.='</li>'; } $str.='</ul>'; return $str; } /** * 输出分类 */ function navList($pid){ $navArr = getCategorys($pid); return nav($navArr); } echo navList(0); }catch(PDOException $e){ echo $e->getMessage(); }
分类输出拆分为了两步:分类遍历-数据输出。
在遍历分类的时候同样需要用到递归遍历,遍历当前分类的同时判断是否有子分类,有则继续遍历子分类。
最终的无限极分类效果: