代码:php
/** * 无限分类查询,默认 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 **无限分类的编辑,因为在编辑的时候其父级是可选择的,因此有可能形成用户选择到当前节点的子节点(们),因此要进行判断。虽然说是无限分类,但正常状况下目录深度是会有限度的,若是给定了目录深度,还要判断选择父级以后的目录深度是否超出范围。
若是将编辑的元素放在其子元素下,所形成的问题:在查询的时候无限循环!!mysql
idsql |
pid框架 |
namefetch |
1this |
0spa |
test1orm |
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则能够进行修改。
(若是不用无限分类查询,只是普通的查询,让前端去实现结果的显示会怎么样呢??不懂那些框架是怎么实现的,感受也是在用递归)