PHP无限级分类

  • 2019-07-26
  • 165
  • 0

无限级递归实现

每一个分类都需要记录它父级id,当为顶级分类时,父级id为0,这样无论哪个分类,都可以通过父级id一层层去查它所有的父级,以便清楚知道它属于何种分类,层级深度为多少。
数据表设计

下拉列表

DROP TABLE IF EXISTS `deepcate`;
CREATE TABLE `deepcate` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `pid` int(10) unsigned NOT NULL,
  `catename` varchar(30) NOT NULL,
  `cateorder` tinyint(10) unsigned NOT NULL DEFAULT '0',
  `createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;

示例

function get_conn()
{
    $username = 'root';
    $password = 'root';
    try
    {
        $dsn ='mysql:host=localhost;dbname=test;port=3306';
        $driver_option = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'set names utf8');
        $pdo = new PDO($dsn, $username, $password, $driver_option);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    } catch (PDOException $e) {
        echo $e->getMessage();
        exit;
    }
}

/**
 * @param int $pid 父分类id
 * @param array $result 返回的数组
 * @param int $spac  递归深度
 * @return array
 */
function get_list($pid = 0, &$result = [], $spac = 0)
{
    $spac += 2;
    $pdo = get_conn();
    $sql = "select * from deepcate where pid ='{$pid}'";
    $res = $pdo->query($sql)->fetchAll();
    foreach ($res as $r)
    {
        $r['catename'] = str_repeat('  ', $spac).'|--'.$r['catename'];
        $result[] = $r;
        get_list($r['id'], $result, $spac);
    }

    return $result;
}

/**
 * @param int $pid    父id
 * @param int $selected  默认被选中的id
 * @return string
 */
function category_select($pid = 0, $selected = 0)
{
    $res = get_list($pid);
    $str = '';
    $str .= "<select name='cate'>";
    $selected_str = '';
    foreach ($res as $r)
    {
        if ($r['id'] == $selected)
        {
            $selected_str = "selected";
        }
        $str .= "<option value='{$r['id']}' {$selected_str}>{$r['catename']}</option>";
    }

    return $str .= '</select>';
}


$str = category_select();
echo $str;

导航条实现

/**
 * @param int $pid 当前id
 * @param array $result 返回的数组
 * @return array
 */
function get_cate_path($cid, &$result = [])
{
    $pdo = get_conn();
    $sql = "select * from deepcate where id ='{$cid}'";
    $res = $pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
    if ($res)
    {
        $result[] = $res;
        // 根据pid去查
        get_cate_path($res['pid'], $result);
    }
    krsort($result);
    return $result;
}

function build_link($id)
{
    $result = get_cate_path($id);
    $link_str = '';
    foreach ($result as $val)
    {
        $link_str .= "<a href='cate.php?'cid={$val['id']}>{$val['catename']}</a>&nbsp;&nbsp;";
    }
    return $link_str;
}

echo build_link(10);

全路径无限分类原理

以一个字段把它所有的父级ID按顺序记录下来以此实现的无线级分类叫做全路径无限分类。利用全路径字段比如(1,2,3,4)这样加上ID组成新字段正序排列,然后再利用字段长度以逗号分隔来计算出层级深度。优点,查询方便;缺点,增加,移动分类时数据维护稍微复杂。

下拉列表实现

function full_path()
{
    $conn = get_conn();
    $sql = "SELECT id, catename, path, CONCAT( path,  ',', id ) AS fullpath FROM  `link` WHERE 1 ORDER BY fullpath ASC ";
    $res = $conn->query($sql)->fetchAll();
    $result = [];
    foreach ($res as $v)
    {
        $fullpath = trim($v['fullpath'], ',');
        $deep = count(explode(',', $fullpath));
        $v['catename'] = str_repeat('&nbsp;&nbsp', $deep).'|----'.$v['catename'];
        $result[] = $v;
    }
    return $result;
}


function category_select()
{
    $res = full_path();
    $str = '';
    $str .= "<select name='cate'>";
    $selected_str = '';
    foreach ($res as $r)
    {
        $str .= "<option value='{$r['id']}'>{$r['catename']}</option>";
    }
    return $str .= '</select>';
}

echo category_select();

导航条实现

function get_nav($cateid)
{
    $conn = get_conn();
    $sql = "select *,concat(path, ',', id) fullpath from link where id = '{$cateid}'";
    $res = $conn->query($sql)->fetch();
    $ids = $res['fullpath'];
    $sqls = "select * from link where id in($ids) order by id asc";
    $new_arr = [];
    $result = $conn->query($sqls)->fetchAll();
    foreach ($result as $v)
    {
        $new_arr[] = $v;
    }
    return $new_arr;
}



function display_cate($cateid, $link = 'cate.php?cid=')
{
    $res = get_nav($cateid);
    $str = '';
    foreach ($res as $k => $v)
    {
        $str .= "&nbsp;&nbsp;&nbsp;<a href='{$link}{$v['id']}'>{$v['catename']}</a>";
    }

    return $str;
}
echo display_cate(4);

评论

还没有任何评论,你来说两句吧

粤ICP备17155863号

- 友情链接 - Theme by Qzhai