热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

thinkphp实现左右值增、改、删操作类

提供各种官方和用户发布的代码示例,代码参考,欢迎大家交流学习
新手,写了基本功能,未写排序等相关操作;求高手改进,
数据库:

类库文件:
Category.class.php /**
应用基于thinkphp的左右值无限分类
**/
class Category
{
//传入实化的对象【M('表名')】
private $objCategory;
//基础节点ID号
public $intCurrentId;
//设置制表符样式
private $arrTabsStyle = array(
'indent' => ' ',
'process' => '├ ',
'end'=>'└ '
);
//构造函数初始化
public function __construct($objCategory)
{
$this->objCategory = $objCategory;
}
//验证传入ID【大于0的数字】
private function checkFun($intId)
{
//$intId优先验证
if(isset($intId))
{
$this->intCurrentId = $intId;
return true;
}
//如果$this->intCurrentId 已设置,验证
else
{
if(isset($this->intCurrentId))
{
return true;
}
else
{
return false;
}
}
}
//根据ID号获取当前节点左右值
private function setCurrentData($intId)
{
if(false == $this->checkFun($intId))
{
return false;
}
$map['id'] = $this->intCurrentId;
return $this->objCategory->field(array('lft','rgt'))->where($map)->find();
}
/*
*作用:
设置输出列表数据的制表符样式
*参数:
$key:arrTabsStyle的KEY
$value:arrTabsStyle的值
*/
public function setTabStyle($key, $value = '')
{
if(isset($this->arrTabsStyle[$key]))
{
$this->arrTabsStyle[$key] = $value;
}
}
/*
*作用:
根据ID号获取当前节点数据
*参数:
$intId:可设置的,需读取节点ID号
*/
public function getCurrentData($intId)
{
if(false == $this->checkFun($intId))
{
return false;
}
$map['id'] = $this->intCurrentId;
return $this->objCategory->field(array('id','title'))->where($map)->find();
}
/*
*作用:
获取当前节点的父节点数据
*参数:
$intId:需要读取节点的ID
*/
public function getParentCategoryData($intId)
{
$arrRoot = $this->setCurrentData($intId);
if($arrRoot)
{
$map['lft'] = array('LT', $arrRoot['lft']);
$map['rgt'] = array('GT', $arrRoot['rgt']);
return $this->objCategory->where($map)->find();
}
else
{
return false;
}
}
/*
*作用:
获取ID下节点列表
*参数:
$intId:需要读取节点的父ID
$intLevel:目录等级默认到100级
*/
public function getCategoryList($intId = 1, $intLevel = 100)
{
//获取选定节点左右值,得出取值区间
$arrRoot = $this->setCurrentData($intId);
if($arrRoot)
{
//读取数据库符合条件的数据
$map['lft'] = array('BETWEEN', array($arrRoot['lft'], $arrRoot['rgt']));
$arrChildList = $this->objCategory->where($map)->order('lft')->select();
//return $arrChildList;
//对取出数据进行格式化
$arrRight = array();
foreach($arrChildList as $v)
{

if(count($arrRight))
{
while ($arrRight[count($arrRight) - 1] <$v[&#039;rgt&#039;])
{
array_pop($arrRight);
}
}
//设置读取目录等级
if($intLevel > count($arrRight))
{
$title = $v[&#039;title&#039;];
//设置输出时的样式
if(count($arrRight))
{
$title = $this->arrTabsStyle[&#039;process&#039;].$title;
}
$title = str_repeat($this->arrTabsStyle[&#039;indent&#039;], count($arrRight)).$title;
$returnCategoryList[] = array(&#039;id&#039;=>$v[&#039;id&#039;],&#039;title&#039;=>$title,&#039;lft&#039;=>$v[&#039;lft&#039;],&#039;rgt&#039;=>$v[&#039;rgt&#039;]);
$arrRight[] = $v[&#039;rgt&#039;];
}
}
return $returnCategoryList;
}
return false;
}
/*
*作用:
获取节点的子节点数
*参数:
$intId:需要读取节点的父ID
*/
public function getCategoryCount($intId)
{
$arrRoot = $this->setCurrentData($intId);
return ($arrRoot[&#039;rgt&#039;] - $arrRoot[&#039;lft&#039;] - 1) / 2;
}
/*
*作用:
添加节点
*参数:
$bolType:true添加到节点前面,false添加到节点尾部
$intId:添加到的父节点
*/
public function insertCategory($bolType = false, $intPid)
{
$data = I(&#039;param.&#039;);
if(!isset($intPid))
{
$intPid = $data[&#039;pid&#039;];
}
$arrRoot = $this->setCurrentData($intPid);
if($arrRoot)
{
if($bolType)
//true添加到节点前面
{
$this->objCategory->where(&#039;rgt>&#039;.$arrRoot[&#039;lft&#039;])->setInc(&#039;rgt&#039;,2);
$this->objCategory->where(&#039;lft>&#039;.$arrRoot[&#039;lft&#039;])->setInc(&#039;lft&#039;,2);
//设置当前节点的左右值
$data[&#039;lft&#039;] = $arrRoot[&#039;lft&#039;] + 1;
$data[&#039;rgt&#039;] = $arrRoot[&#039;lft&#039;] + 2;
}
else
//false添加到节点尾部
{
$this->objCategory->where(&#039;rgt>=&#039;.$arrRoot[&#039;rgt&#039;])->setInc(&#039;rgt&#039;,2);
$this->objCategory->where(&#039;lft>&#039;.$arrRoot[&#039;rgt&#039;])->setInc(&#039;lft&#039;,2);
$data[&#039;lft&#039;] = $arrRoot[&#039;rgt&#039;];
$data[&#039;rgt&#039;] = $arrRoot[&#039;rgt&#039;] + 1;
}
return $this->objCategory->add($data);
}
else
{
return false;
}
}
/*
*作用:
删除节点
*参数:
$intId:被删除的节点ID
*/
public function deleteCategory($intId)
{
$arrRoot = $this->setCurrentData($intId);
if($arrRoot)
{
$ints = $arrRoot[&#039;rgt&#039;] - $arrRoot[&#039;lft&#039;] + 1;
$map[&#039;lft&#039;] = array(&#039;BETWEEN&#039;, array($arrRoot[&#039;lft&#039;], $arrRoot[&#039;rgt&#039;]));
$this->objCategory->where($map)->delete();
$this->objCategory->where(&#039;lft>&#039;.$arrRoot[&#039;rgt&#039;])->setDec(&#039;lft&#039;,$ints);
$this->objCategory->where(&#039;rgt>&#039;.$arrRoot[&#039;rgt&#039;])->setDec(&#039;rgt&#039;,$ints);
return true;
}
else
{
return false;
}
}
/*
*作用:
更新节点
*参数:
$intId:被删除的节点ID
*/
public function updateCategory()
{
//读取POST数据存入数组
$data = I(&#039;param.&#039;);
//父ID等于子ID,直接跳出
if($data[&#039;pid&#039;] == $data[&#039;id&#039;]){return false;}
//post.pid和当前父post.old相等说明未改变目录,不更新左右值
if($data[&#039;pid&#039;] !== $data[&#039;oldpid&#039;])
{
/**********************************【读取所需的相关值】********************************/
//获取新的父节点的数据
$arrParent = $this->setCurrentData($data[&#039;pid&#039;]);
//取当前节点的数据
$arrCurrent = $this->setCurrentData($data[&#039;id&#039;]);
/* 任务:删除节点 */
/**********************************【A-1:隔离数据】************************************/
//将需要调整位置的左右值+100000
$map[&#039;lft&#039;] = array(
array(&#039;EGT&#039;, $arrCurrent[&#039;lft&#039;]),
array(&#039;ELT&#039;, $arrCurrent[&#039;rgt&#039;])
);
$this->objCategory->where($map)->setInc(&#039;lft&#039;,100000);
//因为左值已更新,所以条件变化+100000
$map[&#039;lft&#039;] = array(
array(&#039;EGT&#039;, $arrCurrent[&#039;lft&#039;] + 100000),
array(&#039;ELT&#039;, $arrCurrent[&#039;rgt&#039;] + 100000)
);
$this->objCategory->where($map)->setInc(&#039;rgt&#039;,100000);
unset($map);
/**********************************【A-2:更新正常节点值】******************************/
//获取隔离节点后续更新的步长值
$intStep = $arrCurrent[&#039;rgt&#039;] - $arrCurrent[&#039;lft&#039;] + 1;
//更新节点左右值
$map[&#039;lft&#039;] = array(
array(&#039;GT&#039;, $arrCurrent[&#039;rgt&#039;]),
array(&#039;LT&#039;, 100000)
);
$this->objCategory->where($map)->setDec(&#039;lft&#039;,$intStep);
unset($map);
$map[&#039;rgt&#039;] = array(
array(&#039;GT&#039;, $arrCurrent[&#039;rgt&#039;]),
array(&#039;LT&#039;, 100000)
);
$this->objCategory->where($map)->setDec(&#039;rgt&#039;,$intStep);
unset($map);
/* 完成:删除节点 */
/* 任务:更新节点 */
/**********************************【B-1:新父节目点提供下级节点的空间】****************/
$map[&#039;lft&#039;] = array(
array(&#039;GT&#039;, $arrParent[&#039;lft&#039;]),
array(&#039;LT&#039;, 100000)
);
$this->objCategory->where($map)->setInc(&#039;lft&#039;,$intStep);
unset($map);
$map[&#039;rgt&#039;] = array(
array(&#039;GT&#039;, $arrParent[&#039;lft&#039;]),
array(&#039;LT&#039;, 100000)
);
$this->objCategory->where($map)->setInc(&#039;rgt&#039;,$intStep);
unset($map);
/**********************************【B-2:将节点放入指定下级的空间】********************/
//获取隔离节点后续更新的步长值
$intStep = 100000 + ($arrCurrent[&#039;lft&#039;] - ($arrParent[&#039;lft&#039;] + 1));
//更新左右值大于父节点左值的节点的左右值
$map[&#039;lft&#039;] = array(
array(&#039;EGT&#039;, $arrCurrent[&#039;lft&#039;] + 100000),
array(&#039;ELT&#039;, $arrCurrent[&#039;rgt&#039;] + 100000)
);
$this->objCategory->where($map)->setDec(&#039;lft&#039;,$intStep);
unset($map);
$map[&#039;rgt&#039;] = array(
array(&#039;EGT&#039;, $arrCurrent[&#039;lft&#039;] + 100000),
array(&#039;ELT&#039;, $arrCurrent[&#039;rgt&#039;] + 100000)
);
$this->objCategory->where($map)->setDec(&#039;rgt&#039;,$intStep);
}
return $this->objCategory->where(&#039;id=&#039;.$data[&#039;id&#039;])->setField(&#039;title&#039;, $data[&#039;title&#039;]);
}
}
?>
使用: class CategoryAction extends CommonAction {
private $objCG;
public function _initialize(){
//导入分类库
import(&#039;@.ORG.Util.Category&#039;);
$this->objCG = new Category(M(&#039;CommonCategory&#039;));
}
//目录列表
public function index($id = 1){
$this->cateorylist = $this->objCG->getCategoryList($id);
$this->display();
}
//添加目录
public function add($id=1){
$this->cateorylist = $this->objCG->getCategoryList($id);
$this->display();
}
//编辑目录
public function edit($id){
if (!empty($id)){
//输出所有的节点
$this->cateorylist = $this->objCG->getCategoryList(1);
//读取当前节点数据
$vo = $this->objCG->getCurrentData($id);
if ($vo){
//读取当前节点的父节点数据
$arrParent = $this->objCG->getParentCategoryData($id);
$vo[&#039;pid&#039;] = $arrParent[&#039;id&#039;];
$this->assign(&#039;vo&#039;,$vo);
$this->display();
}else{
$this->error(&#039;数据不存在!&#039;);
}
}else{
$this->error(&#039;数据不存在!&#039;);
}
}
//添加目录:操作
public function insert(){
$list = $this->objCG->insertCategory();
if ($list !== false)
{
$this->success(&#039;数据保存成功!&#039;);
}
else
{
$this->error(&#039;数据写入错误!&#039;);
}
}
public function delete($id){
if (!empty($id))
{
$result = $this->objCG->deleteCategory($id);
if ($result)
{
$this->success(&#039;删除成功!&#039;);
}
else
{
$this->error(&#039;删除出错!&#039;);
}
}
else
{
$this->error(&#039;ID错误!&#039;);
}
}
public function update(){
$list = $this->objCG->updateCategory();
if ($list !== false)
{
$this->success(&#039;更新成功!&#039;);
}
else
{
$this->error("操作失败!");
}
}
}

AD:真正免费,域名+虚机+企业邮箱=0元

推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 本文描述了作者第一次参加比赛的经历和感受。作者是小学六年级时参加比赛的唯一选手,感到有些紧张。在比赛期间,作者与学长学姐一起用餐,在比赛题目中遇到了一些困难,但最终成功解决。作者还尝试了一款游戏,在回程的路上感到晕车。最终,作者以110分的成绩取得了省一会的资格,并坚定了继续学习的决心。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 关羽败走麦城时路过马超封地 马超为何没有出手救人
    对当年关羽败走麦城,恰好路过马超的封地,为啥马超不救他?很感兴趣的小伙伴们,趣历史小编带来详细的文章供大家参考。说到英雄好汉,便要提到一本名著了,没错,那就是《三国演义》。书中虽 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 橱窗设计的表现手法及其应用
    本文介绍了橱窗设计的表现手法,包括直接展示、寓意与联想、夸张与幽默等。通过对商品的折、拉、叠、挂、堆等陈列技巧,橱窗设计能够充分展现商品的形态、质地、色彩、样式等特性。同时,寓意与联想可以通过象形形式或抽象几何道具来唤起消费者的联想与共鸣,创造出强烈的时代气息和视觉空间。合理的夸张和贴切的幽默能够明显夸大商品的美的因素,给人以新颖奇特的心理感受,引起人们的笑声和思考。通过这些表现手法,橱窗设计能够有效地传达商品的个性内涵,吸引消费者的注意力。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
author-avatar
张伊韵育财育信
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有