欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PHP在无限分类时注意的一些问题(不保证代码完全正确哦)

程序员文章站 2022-07-01 23:19:09
转自:PHP在无限分类时注意的一些问题(http://lxiaoke.cn) (注意:代码使用的是原生PHP,旨在提供解决思路)1 无限分类的查找(获取所有节点) 代码: /** * 无限分类查询,默认 pid 为 0 * @param $pid * @return array $res */ pr ......
(注意:代码使用的是原生php,旨在提供解决思路)
1 无限分类的查找(获取所有节点)

代码:

/**
 * 无限分类查询,默认 pid 为 0
 * @param $pid
 * @return array $res
 */
protected function selecttree($pid = 0)
{
    $res = [];
    $sql = "select * from " . $this->tbname . " where pid=" . $pid;
    $result = @mysqli_query($this->link, $sql);
    if ($result) {
        $count = mysqli_num_rows($result);
        if ($count > 0) {
            while ($rows = mysqli_fetch_assoc($result)) {
                $rows['children'] = $this->selecttree($rows['id']);
                $res[] = $rows;
            }
        }
        mysqli_free_result($result);
    }
    return $res;
}

 

2 无限分类节点的删除,不能单纯地删除当前节点,需要查找到当前节点下的所有子节点,一并删除

代码:

/**
 * 删除目录树
 * @param $id
 */
protected function deletetree($id)
{
    $res = $this->selecttree($id);
    if (!empty($res)) {
        foreach ($res as $v) {
            $this->deletetree($v['id']);
        }
    }
    $sql = "delete from " . $this->tbname . " where id=" . $id;
    mysqli_query($this->link, $sql);
}
3 **无限分类的编辑,由于在编辑的时候其父级是可选择的,所以有可能造成用户选择到当前节点的子节点(),所以要进行判断。虽说是无限分类,但正常情况下目录深度是会有限度的,如果给定了目录深度,还要判断选择父级之后的目录深度是否超出范围。

如果将编辑的元素放在其子元素下,所造成的问题:在查询的时候无限循环!!

id

pid

name

1

0

test1

2

1

test2

修改之后:

id

pid

name

1

2

test1

2

1

test2

如上表所示,在进行无限分类查询时,就会陷入死循环!

所以,针对可能会出现的问题,给出下面的解决办法,在用户修改时进行判断,通过则可以修改,未通过则给出提示。

3.1 判断用户选择的是否是当前节点(这个只需要判断选择的节点和当前编辑节点的id是否相同即可)

3.2 判断用户选择的是否是子节点(如果是的话返回true   

 

/**
 * 判断id所对应的元素是否是pid所对应元素的子元素,是的话返回true
 * @param $id
 * @param $pid
 * @return boolean $result
 */
protected function ischild($id, $pid)
{
    $result = false;
    $sql = "select pid from " . $this->tbname . " where id=" . $id;
    $res = @mysqli_query($this->link, $sql);
    if ($res) {
        while ($rows = mysqli_fetch_assoc($res)) {
            $result = ($pid === $rows['pid']) ? true : (($rows['pid'] !== 0) ? $this->ischild($rows['pid'], $pid) : false);
        }
    }
    return $result;
}

3.3 判断用户选择的节点是否已经达到目录深度

在做完后面的一步之后,这一步就比较好实现了:

/**
 * 判断所选元素是否达到目录深度,达到返回true
 * @param $id
 * @return mixed
 */
protected function ismaxdeep($id)
{
    return $this->deepup($id) >= $this->maxdeep;
}

3.4 判断修改之后的目录深度是否超出限定范围

 

/**
 * 修改之后的最终深度,如果深度大于规定深度,返回true
 * @param $pid
 * @param $id
 * @return mixed
 */
protected function lastdeep($pid, $id)
{
    return ($this->deepup($pid) + $this->deepdown($id)) > $this->maxdeep;
}

/**
 * 向上查找父元素的深度
 * @param $id
 * @param int $k
 * @return int
 */
protected function deepup($id, $k = 1)
{
    $sql = "select pid from " . $this->tbname . "where id=" . $id;
    $res = @mysqli_query($this->link, $sql);
    if ($res) {
        while ($rows = mysqli_fetch_assoc($res)) {
            ($rows['pid'] !== 0) && $k = $this->deepup($rows['pid'], $k+1);
        }
    }
    return $k;
}

/**
 * 向下查找子元素的深度
 * @param $id
 * @param int $k
 * @return int
 */
protected function deepdown($id, $k = 0)
{
    $sql = "select * from " . $this->tbname . "where pid=" . $id;
    $res = @mysqli_query($this->link, $sql);
    if ($res && mysqli_num_rows($res) > 0) {
        $k++;
        while ($rows = mysqli_fetch_assoc($res)) {
            $k = max($k, $this->deepdown($rows['id'], $k))
        }
    }
    return $k;
}

经过上面的判断之后,根据返回的结果就能判断是否可以修改,如果返回true,则不可以修改,如果是false则可以进行修改。

(如果不用无限分类查询,只是普通的查询,让前端去实现结果的显示会怎么样呢??不懂那些框架是怎么实现的,感觉也是在用递归)