代码:
/**
* 无限分类查询,默认 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则可以进行修改。
(如果不用无限分类查询,只是普通的查询,让前端去实现结果的显示会怎么样呢??不懂那些框架是怎么实现的,感觉也是在用递归)
原文:https://www.cnblogs.com/Super-Lee/p/10847651.html