无限级分类的简单实例 [ 未指定版本 ]
<?php
//模拟一个分类数组
$area = array(
array('id'=>1,'name'=>'安徽','parent'=>0),
array('id'=>2,'name'=>'海淀','parent'=>7),
array('id'=>3,'name'=>'濉溪县','parent'=>5),
array('id'=>4,'name'=>'昌平','parent'=>7),
array('id'=>5,'name'=>'淮北','parent'=>1),
array('id'=>6,'name'=>'朝阳','parent'=>7),
array('id'=>7,'name'=>'北京','parent'=>0),
array('id'=>8,'name'=>'上地','parent'=>2)
);
/**
*递归,查找子孙树
*/
function subtree($arr,$id=0,$lev=1) {
$subs = array(); // 子孙数组
foreach($arr as $v) {
if($v['parent'] == $id) {
$v['lev'] = $lev;
$subs[] = $v; // 举例说找到array('id'=>1,'name'=>'安徽','parent'=>0),
$subs = array_merge($subs,subtree($arr,$v['id'],$lev+1));
}
}
return $subs;
}
$tree = subtree($area,0,1);
//string str_repeat ( string $input , int $multiplier )
//返回 input 重复 multiplier 次后的结果。
foreach($tree as $v) {
echo str_repeat(' |- ',$v['lev']),$v['name'],'<br />'; //str_repeat — 重复一个字符串
}
/**
*结果
*/
/*
|- 安徽
|- |- 淮北
|- |- |- 濉溪县
|- 北京
|- |- 海淀
|- |- |- 上地
|- |- 昌平
|- |- 朝阳
*/
/**
*递归,求家谱树
*/
function familytree($arr,$id) {
$tree = array();
foreach($arr as $v) {
if($v['id'] == $id) {// 判断要不要找父栏目
if($v['parent'] > 0) { // parnet>0,说明有父栏目
$tree = array_merge($tree,familytree($arr,$v['parent']));
}
$tree[] = $v; // 以找到上地为例
}
}
return $tree;
}
print_r(familytree($area,8)); // 北京->海淀->上地
echo "<br>";
/**
*迭代,求家谱树
*/
// 迭代,效率比递归高,代码也没多.
// 找家谱树推荐用迭代
function tree($arr,$id) {
$tree = array();
while($id !== 0) {
foreach($arr as $v) {
if($v['id'] == $id) {
$tree[] = $v;
$id = $v['parent'];
break;
}
}
}
return $tree;
}
print_r(tree($area,8));
?>
lin_lin
注册时间:2015-06-23
最后登录:2023-07-18
在线时长:33小时36分
最后登录:2023-07-18
在线时长:33小时36分
- 粉丝12
- 金钱1945
- 威望20
- 积分2475
共 3 条评论
请问一下这个哪里会用到
在产品目录或栏目设置的时候可以参考下
濉溪的老乡?
哈哈,不是哦
<?php /** * 数据处理类 */ final class Data { /** * 本函数即将废弃 * @param $data * @param string $fieldPri * @param string $fieldPid * @param int $pid * @param null $sid * @param int $type 1 获得多层栏目 | 2 获得所有子栏目 3 获得父级栏目 4 判断是否为子栏目 * @param string $html * @param int $level * @return array|bool */ static public function channel($data, $fieldPri = 'cid', $fieldPid = 'pid', $pid = 0, $sid = null, $type = 2, $html = " ", $level = 1) { switch ($type) { case 1: return self::channelLevel($data, $pid, $html, $fieldPri, $fieldPid, $level); case 2: return self::channelList($data, $pid, $html, $fieldPri, $fieldPid, $level); case 3: return self::parentChannel($data, $sid, $html, $fieldPri, $fieldPid, $level); case 4: return self::isChild($data, $sid, $pid, $fieldPri, $fieldPid); } } /** * 获得所有子栏目 * @param $data 栏目数据 * @param int $pid 操作的栏目 * @param string $html 栏目名前字符 * @param string $fieldPri 表主键 * @param string $fieldPid 父id * @param int $level 等级 * @return array */ static public function channelList($data, $pid = 0, $html = " ", $fieldPri = 'cid', $fieldPid = 'pid', $level = 1) { if (!$data) { return array(); } $arr = array(); $id = 0; foreach ($data as $v) { if ($v[$fieldPid] == $pid) { $arr[$id] = $v; $arr[$id]['level'] = $level; $arr[$id]['html'] = str_repeat($html, $level - 1); $sArr = self::channelList($data, $v[$fieldPri], $html, $fieldPri, $fieldPid, $level + 1); $arr = array_merge($arr, $sArr); $id = count($arr); } } return $arr; } /** * 返回多层栏目 * @param $data 操作的数组 * @param int $pid 一级PID的值 * @param string $html 栏目名称前缀 * @param string $fieldPri 唯一键名,如果是表则是表的主键 * @param string $fieldPid 父ID键名 * @param int $level 不需要传参数(执行时调用) * @return array */ static public function channelLevel($data, $pid = 0, $html = " ", $fieldPri = 'cid', $fieldPid = 'pid', $level = 1) { if (!$data) { return array(); } $arr = array(); foreach ($data as $v) { if ($v[$fieldPid] == $pid) { $arr[$v[$fieldPri]] = $v; $arr[$v[$fieldPri]]['html'] = str_repeat($html, $level - 1); $arr[$v[$fieldPri]]["Data"] = self::channelLevel($data, $v[$fieldPri], $html, $fieldPri, $fieldPid, $level + 1); } } return $arr; } /** * 获得所有父级栏目 * @param $data 栏目数据 * @param $sid 子栏目 * @param string $html 栏目名称前缀 * @param string $fieldPri 唯一键名,如果是表则是表的主键 * @param string $fieldPid 父ID键名 * @return array */ static public function parentChannel($data, $sid, $html = " ", $fieldPri = 'cid', $fieldPid = 'pid') { if (!$data) { return array(); } static $arr = array(); foreach ($data as $v) { if ($v[$fieldPri] == $sid) { $arr[] = $v; $sArr = self::parentChannel($data, $v[$fieldPid], $html, $fieldPri, $fieldPid); $arr = array_merge($arr, $sArr); } } return $arr; } /** * 判断$s_cid是否是$d_cid的子栏目 * @param $data 栏目数据 * @param $sid 子栏目id * @param $pid 父栏目id * @param string $fieldPri 主键 * @param string $fieldPid 父id字段 * @return bool */ static function isChild($data, $sid, $pid, $fieldPri = 'cid', $fieldPid = 'pid') { $_data = self::channelList($data, $pid, "", $fieldPri, $fieldPid); foreach ($_data as $c) { //目标栏目为源栏目的子栏目 if ($c['cid'] == $sid) return true; } return false; } /** * 递归实现迪卡尔乘积 * @param $arr 操作的数组 * @param array $tmp * @return array */ static function descarte($arr, $tmp = array()) { static $n_arr = array(); foreach (array_shift($arr) as $v) { $tmp[] = $v; if ($arr) { self::descarte($arr, $tmp); } else { $n_arr[] = $tmp; } array_pop($tmp); } return $n_arr; } } ?>
无限极分类!
@dafa168 哈哈,很好