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

转自:PHP在无限分类时注意的一些问题(http://lxiaoke.cn)

(注意:代码使用的是原生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则可以进行修改。

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

原文地址:https://www.cnblogs.com/Super-Lee/p/10847651.html

时间: 2024-08-01 16:18:01

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

深度实现session【包括session入库、session机制和session和cookie的使用方法,完善会话机制(在分布式机器中也能使用)】、无限分类的实现

1.session的注意点:@session_start();//这个配置需要注意,session开启中会有影响,所以使用错误抑制符进行限制[并且使用php.ini对session进行自动开启] session_start()前的输出问题:[session信息本身会增加到http头信息,也就是http主体不能在头前]对php.ini中的输出缓存进行配置,out_buffer的配置[注意:开启之后能够保证输出内容在脚本中缓存] [注意](1)脚本中session变量的键只能是字符串类型的[$_SE

php不用递归完成无限分类,从表设计入手完整演示过程

无限分类是什么就不废话了,可以用递归实现,但是递归从数据库取东西用递归效率偏低,如果从表设计入手,就很容易做到网站导航的实现,下面是某论坛导航,如下图 网上无限分类大多不全面,今天我会从设计表开始, 首先我们先做视图界面, <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>白超华-博客园</title> &

无限分类1

连接上一个 无限分类 一.新建一个商品表 cid对应上面的ID 二. //获取所有的数据 $pdo = new PDO("mysql:host=localhost;dbname=lamp108",'root',''); $pdo->query("set names gbk"); $stmt = $pdo->query("select * from cate2"); $data = $stmt->fetchAll(2); func

无限分类树操作

获取相应分类id的分类树: public static function getCategoryTree($id){ //$model=M('category'); if($id>0){ $obj=self::selectTable('category',array('id'=>$id),true);//$model->where(array('id'=>$id))->find(); if(!is_null($obj)){ $childList=self::selectTab

php基于左右值排序的无限分类算法

PHP无限分类[左右值]算法 <?php /** * 基于左右值排序的无限分类算法 * 数据库结果为 CREATE TABLE om_catagory ( CatagoryID int(10) unsigned NOT NULL auto_increment, Name varchar(50) default '', Lft int(10) unsigned NOT NULL default '0', Rgt int(10) unsigned NOT NULL default '0', PRIM

递归无限分类笔记

最近项目都上线了每天巩固一下php知识,下面是关于递归无限分类的比较供大家参考! 数据库一个表就可以了,增加一个parendid字段 也就是子级分类 ,排序大家也可以加一下字段. CREATE TABLE `category` (   `id` int(11) NOT NULL,   `name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,   `sort_order` int(11) DEFAULT NULL,   `parendid` int(

PHP无限分类树算法相关

一.找儿子 1.引用算法找儿子 /**  * 创建子节点树形数组  * 参数  * $ar 数组,邻接列表方式组织的数据  * $id 数组中作为主键的下标或关联键名  * $pid 数组中作为父键的下标或关联键名  * 返回 多维数组  **/ function find_child($ar, $id='id', $pid='pid') {     foreach($ar as $v) $t[$v[$id]] = $v;     foreach ($t as $k => $item){    

初学递归,接触无限分类,小小的尝试

今日学习的是无限循环,这与递归有关.其实我自己还不是完全熟悉和上手,还需要琢磨琢磨. 初步学习递归,算是无限分类的一个小练习. 表:cate id int auto 自动递增 pid int 0为最大的分类 catename varchar 分类名称 读取数据库的cate表分类如下: //分类练习 include '../include.php'; function getList($pid=0,&$result=array(),$spac=0) { $spac = $spac + 4; $sq

数据库结果为 基于左右值排序的无限分类算法

<?php /**     * 基于左右值排序的无限分类算法     * 数据库结果为 CREATE TABLE om_catagory (      CatagoryID int(10) unsigned NOT NULL auto_increment,     Name varchar(50) default '',      Lft int(10) unsigned NOT NULL default '0',      Rgt int(10) unsigned NOT NULL defau