<?php
/* 名称: 对分类操作的业务逻辑封装
*
* 作者: 帅的像人渣QQ: 1191391E-mail:
netcat2@21cn.com*
* 完成日期: 2003-12-18 13:33
*
* 说明: 本类中引用的其它类(DB、Table、Item)均未提供,所以本类只能做个参考,不能直接应用
*不是本人小气不提供其它类,实在是因为那些都是一两年前写的类,很烂。怕大家看后对大
*造成误导. 在此发表这个类,只希望大家能从中学到一些程序设计的方法。
*授人以鱼不如授人以渔~
*
* 特点:
*采用递归调用的方法,对分类数据只需一次数据库查询可生成树状结构。 无限递归层次(视机器堆栈而定)
*
* 数据库定义:
*IDsmallint unsignedprimary#如果数据量很大可用int
*ParentIDsmallint unsignedindex#如果数据量很大可用int, 请索引此字段
*#如果为根分类,则ParentID = 0
*
*RootIDsmallint unsignedindex#如果数据量很大可用int, 请索引此字段
*#如果是根分类则RootID = 0, 否则RootID = 最上层的父分类ID
*CategoryName varchar(n)#此大小自定
*如需有其它字段定义附在后面
* 注意事项:
*不要试图直接调用本类,除非你有和我定义那另外那几个类相对应的接口, 否则不会成功
*在合适的地方定义 DBTABLE_CATEGORY 这个常量,使其指向你的分类数据表名字
*
* 程序构架:
*├─基础类<!-- 完成底层数据库操作、数据抽象、语言、模板、异常、杂项等)操作 -->
*│
*│
*└─业务逻辑层(此类所处层次)<!-- 利用基础类中数据操作、数据抽象等类根据表现层传递的参数完成数据处理,并返回数据或操作结果 -->
*│
*│
*└───表现层(用户界面)<!-- 利用业务逻辑层将取得的数据或操作数据的结果通过基础类中的界面等类进行显示 -->
*/
define('DBTABLE_CATEGORY', 'xxx');
class Category_Logic
{
var $KernelRef= NULL;//系统核心的引用
var $tblObj= NULL;//包含当前分类数据 Table 类的实例
var $_CurrentItem= NULL;//包含当前分类数据 TItem类的实例
var $CategoryID= 0;//当前分类ID,如果没有当前分类此项为 0
//---------------------------------------------------------------------------
//privatearray GetNodeData(array $Data, int $ParentNode)
//根据一颗指定根的并且以兄弟双亲法表示的树和当前分类的ID,返回当前分类在整个分类表中所处的位置
//
// @param: $Data2维数组Array(
//Array(
//'ID'=> 分类ID,
//'ParentID'=> 父分类ID,
//'RootID'=> 根分类ID,
//'CategoryName'=> 分类名称,
//),
//……
//);
//表示的一颗树
//
// @param: $ParentNode父分类ID, 每一次由调用者给出,递归时由程序计算传递
//
// return value:返回以兄弟双亲法表示的所有分类的树
//注意: 确保当前分类已经设置,否则此函数无返回
//
//---------------------------------------------------------------------------
function GetNodeData($Data, $ParentNode)
{
$arr = Array();
$ArrayCount = 0;
for($i = 0, $cnt = Count($Data); $i < $cnt; $i++)
{
if($Data[$i]['ParentID'] == $ParentNode)
{
$arr[$ArrayCount]=$Data[$i];
$arr[$ArrayCount++]['Child']=$this->GetNodeData($Data, $Data[$i]['ID']);
}
}
return $arr;
}
//---------------------------------------------------------------------------
//privateString _CurrentLevel(array $Data, int $Current, String $ProcessFunc = '')
//根据一颗指定根的并且以兄弟双亲法表示的树和当前分类的ID,返回当前分类在整个分类表中所处的位置
//
// @param: $Data兄弟双亲法表示的树, 由调用者传递
//
// @param: $Current当前分类ID,第一次调用时由调用者给出,递归时由程序自行计算
//
// @param: $ProcessFunc指定对分类数据的处理函数, 函数原型定义见 $this->PrintCurrentLevel 中的注释
//
// return value:返回当前分类在分类树中的位置
//注意: 确保当前分类已经设置,否则此函数无返回
//
//---------------------------------------------------------------------------
function _CurrentLevel($Data, $Current, $ProcessFunc = '')
{
for($i = 0; $i < Count($Data); $i++)
{
if($Data[$i]['ID'] == $Current)
{
if($Data[$i]['ParentID'] != 0)
{
$str = $this->_CurrentLevel($Data, $Data[$i]['ParentID'], $ProcessFunc) . ' -> ';
if($ProcessFunc) $str .= $ProcessFunc($Data[$i]);
else $str .= $Data[$i]['CategoryName'];
}
else
{
if($ProcessFunc) $str = $ProcessFunc($Data[$i]);
else $str = $Data[$i]['CategoryName'];
}
break;
}
}
return $str;
}
//---------------------------------------------------------------------------
//publicCategory_Logic(Object &$Kernel, int $CategoryID = -1)
//本类构造函数
//
// @param: $Kernel此参数为当前系统核心类的一个引用, 核心类中包括
//数据库类、输入输出类、系统配置类等
//
// @param: $CategoryID当前分类ID。
//当想调用 PrintCurrentLevel、GetRootID、GetParentID、GenerateTypeTreeList及
//调用_CurrentItem成员的方法时请先设置此值.
//
//调用GenerateTypeTreeList时设置此值,则没有ID为此的分类默认被选择,没设置则无默认
//
// return value:none
//
//---------------------------------------------------------------------------
function &Category_Logic(&$Kernel, $CategoryID = -1)
{
$this->KernelRef = &$Kernel;
$this->tblObj = new Table($Kernel->DBObj, DBTABLE_CATEGORY);
if($CategoryID != -1)
{
$this->SetCategoryID($CategoryID);
}
}
//---------------------------------------------------------------------------
//publicvoid SetCategoryID(int $CategoryID)
//设置当前分类ID
//
// return value: none
//
//---------------------------------------------------------------------------
function SetCategoryID($CategoryID)
{
if(!$CategoryID) return;
$Item = new TItem($this->KernelRef->DBObj, DBTABLE_CATEGORY, '*', $CategoryID ,'ID');
$this->_SelfData = &$Item;
$this->CategoryID = $CategoryID;
}
//---------------------------------------------------------------------------
//publicint GetRootID()
//返回当前分类的根分类ID
//注意:只有设置的当前分类时此函数才有效
//
// return value:返回当前分类的根分类ID
//
//---------------------------------------------------------------------------
function GetRootID()
{
return $this->_SelfData->Get('RootID');
}
//---------------------------------------------------------------------------
//publicint GetParentID()
//返回当前分类的父分类ID
//注意:只有设置的当前分类时此函数才有效
//
// return value:返回当前分类的父分类ID
//
//---------------------------------------------------------------------------
function GetParentID()
{
if($this->CategoryID) return $this->_SelfData->Get('ParentID');
}
//---------------------------------------------------------------------------
//publicString GenerateTypeTreeList(array $Data, String $ProcessFunc, int $floor = 0)
//返回整个分类的树状结构放在OptionList中的列表
//
// @param: $Data此参数由 $this->DumpTypeDataToTree() 返回
//
// @param: $ProcessFunc处理显示分类信息的回调函数, 函数原型请参照: $this->PrintCurrentLevel()
//
// @param: $floor本参数不能人为给出,是程序自动计算的中间值
//
// return value:
//结构为一颗兄弟双亲表示法表示的树
//设如分类数据如下:
//├──1级分类
//│
//│
//│
//├─2级分类
//│ │
//│ └─3级分类
//│
//└─2级分类
//
//则返回值为 Array(
//0=> Array(
//'ID'=>'',
//'ParentID'=>'',
//'RootID'=>'',
//'CategoryName'=>'',
//'Child'=>....
//)
//.....
//)
//
//---------------------------------------------------------------------------
function DumpTypeDataToTree($RootID = 0, $Fields = '*')
{
$this->tblObj->SetFields($Fields);
$this->tblObj->SetCondition('');
$List = $this->tblObj->MapResult($this->tblObj->Select());
return $this->GetNodeData($List, $RootID);
}
//---------------------------------------------------------------------------
//publicString GenerateTypeTreeList(array $Data, String $ProcessFunc = '', int $floor = 0)
//返回整个分类的树状结构放在OptionList中的列表
//
// @param: $Data此参数由 $this->DumpTypeDataToTree() 返回
//
// @param: $ProcessFunc处理显示分类信息的回调函数, 函数原型请参照: $this->PrintCurrentLevel()
//
// @param: $floor本参数不能人为给出,是程序自动计算的中间值
//
// return value:返回一个<option>分类名称1</option> ... <option>分类名称n</option>
//
// ps: 调用时echo "<select name='xxxx'>" . $_c->GenerateTypeTreeList($Data, 'ProcessFunc') . "</select>";
//
//---------------------------------------------------------------------------
function GenerateTypeTreeList($Data, $ProcessFunc, $floor = 0)
{
$Str = '';
for($i = 0, $cnt = Count($Data); $i < $cnt; $i++)
{
if($this->CategoryID == $Data[$i]['ID'])
{
$Str .= "<option value='{$Data[$i]['ID']}' selected>"
. str_repeat(" ", $floor * 3)
. '├'
. ($ProcessFunc ? $ProcessFunc($Data[$i]) : $Data[$i]['CategoryName'])
. "</option>/n";
}
else
{
$Str .= "<option value='{$Data[$i]['ID']}'>"
. str_repeat(" ", $floor * 3)
. '├'
. ($ProcessFunc ? $ProcessFunc($Data[$i]) : $Data[$i]['CategoryName'])
. "</option>/n";
}
if($Data[$i]['Child']) $Str .= $this->GenerateTypeTreeList($Data[$i]['Child'], $ProcessFunc, $floor + 1);
}
return $Str;
}
//---------------------------------------------------------------------------
//publicString GenerateTypeTreeView(array $Data, String $ProcessFunc = '')
//返回整个分类的树状结构视图
//
// @param: $Data此参数由 $this->DumpTypeDataToTree() 返回
//
// @param: $ProcessFunc处理显示分类信息的回调函数, 函数原型请参照: $this->PrintCurrentLevel()
//
// return value:返回生成的一颗HTML形式显示的树
//
//---------------------------------------------------------------------------
function GenerateTypeTreeView($Data, $ProcessFunc)
{
$Str = '<ul style="Line-Height:200%">';
for($i = 0, $cnt = Count($Data); $i < $cnt; $i++)
{
if($ProcessFunc) $Str .= '<li>' . $ProcessFunc($Data[$i]) . '</li>' . "/n";
else $Str .= '<li>' . $Data[$i]['CategoryName'] . '</li>' . "/n";
if($Data[$i]['Child']) $Str .= '<li>' . $this->GenerateTypeTreeView($Data[$i]['Child'], $ProcessFunc) . '</li>';
}
$Str .= '</ul>';
return $Str;
}
//---------------------------------------------------------------------------
//publicString PrintCurrentLevel(String $ProcessFunc = '')
//对多级分类生成当前位置字符串
//设如分类数据如下,当前分类为3级分类, 则调用返回1级分类 -> 2级分类 -> 3级分类
//├──1级分类
//│
//│
//│
//├─2级分类
//│ │
//│ └─3级分类
//│
//└─2级分类
//
//
//
//
// @param: $ProcessFunc此为对分类数据如何显示的回调函数,不设置则直接显示分类名称
//函数定义原型为function (&$arr);
//其中$arr参数为每一个分类信息的一维数组如下:
//array(ID => 1, ParentID => 0, RootID => 0, CategoryName => '1级分类')
//返回值为对上述数据处理的结果,比如返回带链接的分类名字、更改显示颜色等
//
// return value: 返回当前分类在整个分类树中所处位置
//
//---------------------------------------------------------------------------
function PrintCurrentLevel($ProcessFunc = '')
{
if(!$this->CategoryID) return '';
if($this->_SelfData->Get("RootID") == 0)
{
if($ProcessFunc) return $ProcessFunc($this->_SelfData->fetchDataToArray());
else return $this->_SelfData->Get("CategoryName");
}
$Current = $this->CategoryID;
$this->tblObj->SetCondition('RootID = ' . $this->_SelfData->Get('RootID') . " or ID = " . $this->_SelfData->Get('RootID'));
$Data = $this->tblObj->MapResult($this->tblObj->Select());
return $this->_CurrentLevel($Data, $Current, $ProcessFunc);
}
//---------------------------------------------------------------------------
//publicboolean Add(array $arr)
//添加新分类到分类表中
//
// @param: $arr在此数组中包括对新添加分类的定义, 定义如下:
//
//$arr['RootID']新分类所属的根分类ID
//$arr['ParentID']新分类的父分类ID
//$arr['CategoryName']新分类的名称
//
// return value:返回添加分类操作结果
//
//---------------------------------------------------------------------------
function Add($arr)
{
$this->tblObj->SetFields(
Array(
'RootID',
'ParentID',
'CategoryName',
)
);
return $this->tblObj->Insert(
Array(
$arr['RootID'],
$arr['ParentID'],
$arr['CategoryName'],
)
);
}
//---------------------------------------------------------------------------
//publicboolean Delete(int $ID)
//删除已经存在的分类
//
// @param: $ID要删除的分类ID
//
// return value:返回删除分类操作结果
//
//---------------------------------------------------------------------------
function Delete($ID)
{
$sysOption = &$this->KernelRef->Config;
$this->tblObj->SetFields('*');
$this->tblObj->SetCondition('ID = ' . (int)$ID);
return $this->tblObj->Delete();
}
//---------------------------------------------------------------------------
//publicboolean Modify(int $ID, array $arr)
//修改已经存在的分类
//
// @param: $ID要修改的分类ID
// @param: $arr在此数组中包括修改后的分类定义, 定义如下:
//
//$arr['RootID']新分类所属的根分类ID
//$arr['ParentID']新分类的父分类ID
//$arr['CategoryName']新分类的名称
//
// return value:返回修改分类操作结果
//
//---------------------------------------------------------------------------
function Modify($ID, $arr)
{
$this->tblObj->SetCondition('ID = ' . (int)$ID);
$prev = $this->tblObj->MapOneRow($this->tblObj->Select());
$this->tblObj->SetFields(
Array(
'RootID',
'ParentID',
'CategoryName',
)
);
return $this->tblObj->Update($arr);
}
//---------------------------------------------------------------------------
//publicarray Modify(int $ID)
//修改已经存在的分类
//
// @param: $ID指定的分类ID
//
// return value: 返回指定ID分类的信息
//数组中包括:
//Array(
//'ID'=> 分类ID,
//'ParentID'=> 父分类ID,
//'RootID'=> 根分类ID,
//'CategoryName'=> 分类名称,
//);
//
//---------------------------------------------------------------------------
function GetCategory($ID)
{
$this->tblObj->SetCondition('ID = ' . (int)$ID);
return $this->tblObj->MapOneRow($this->tblObj->Select());
}
}
?>
效果如下:
分享到:
相关推荐
无限级分类允许我们创建一个可以无限深度扩展的分类系统,无需预先设定最大层级。下面我们将深入探讨PHP实现无限级分类的方法、常见算法以及如何结合SQL数据库进行操作。 首先,无限级分类的核心在于每个分类都有一...
无限级分类在IT行业中,特别是在数据...综上所述,这个压缩包提供了一个完整的无限级分类系统的实现,包括后端处理、数据库结构、前端展示以及相关的文档和资源,对于学习和实践无限级分类的开发者来说是非常有价值的。
无限级分类意味着一个分类可以有任意数量的子分类,这些子分类又可以有它们自己的子分类,形成一个无限延伸的树状结构。这种结构非常适合那些层次关系复杂、可能需要不断扩展的场景。 在实现过程中,通常会使用自...
- **保存分类**:处理添加或编辑分类后提交的数据。 - **删除分类**:提供删除现有分类的功能。 - **展示分类列表**:展示了所有分类的信息,并且根据它们之间的层级关系进行了适当的缩进展示,以直观地表示出各个...
本文将深入探讨这些概念,并结合"js无限级分类源码",即JavaScript实现的树型菜单无限分类的功能。 无限级分类是一种数据结构设计,它允许类别可以有任意多的子类,形成一个无限深度的层次结构。这种结构在实际应用...
4. **遍历无限分类**:遍历无限分类数组通常有两种方式:深度优先搜索(DFS)和广度优先搜索(BFS)。DFS常使用递归,先访问子节点再访问父节点;BFS则使用队列,先访问父节点再访问子节点。根据应用场景选择合适的...
在PHP编程中,无限分类是一种常见的需求,尤其在处理如商品分类、文章分类等具有层级关系的数据时。无限分类允许我们构建任意深度的分类结构,而不限制父类与子类的数量。以下将详细介绍如何使用PHP实现无限分类,并...
本文将深入探讨如何使用存储过程来处理这种无限级分类。 首先,`sp_Column_Update.sql` 是一个更新操作的存储过程。在无限级分类中,可能需要修改节点的位置,比如移动子类别到不同的父类别下。存储过程会处理这种...
在IT行业中,数据库和数据结构的管理是至关重要的,特别是在网站开发中,如电商或博客系统,往往需要处理复杂的层级关系,例如商品分类、文章目录等。PHP作为一门广泛使用的服务器端脚本语言,提供了处理无限级分类...
在IT行业中,无限分类是一种常见的数据组织方式,特别是在网站内容管理、电商商品分类、博客文章分类等场景下。...开发者可以根据具体需求,结合提供的`classok`类文件,轻松地在自己的项目中集成无限分类功能。
在ASP中实现无限级分类是一项常见的需求,特别是在处理如产品目录、文章分类等具有层级关系的数据时。无限级分类允许用户灵活地添加任意级别的子分类,而无需预先设定分类的最大深度。 这个"asp无限级分类(含数据库...
`class.asp`中的代码可能包括了获取、添加、编辑和删除分类的方法,以及处理无限级分类的逻辑,如递归函数或者自连接查询。 4. **class.mdb**: 这是一个Access数据库文件,通常包含了存储分类信息的表。表结构...
1. 数据库设计:首先,需要设计一个能够存储无限级别分类的数据模型。通常采用自引用的方式,每个分类都有一个父分类ID,通过这个字段可以链接到上级分类,形成层级关系。例如,一个“商品分类”表,包含“ID”、...
1. **无限级分类的概念**:无限级分类允许类别拥有无限数量的子类,这在大型网站中非常有用,因为它可以灵活地组织大量内容,且易于扩展。例如,在电商网站中,商品可以被归类到品牌 -> 类别 -> 子类别 -> 更细分的...
这里的"无限级分类"指的是在网站内容管理中,允许用户创建任意深度的分类结构,比如一级分类下可有二级分类,二级分类下又可有三级,以此类推,形成无限级别的树形结构。 数据库设计是关键。通常我们会选择关系型...
这样的无限分类系统在电商网站、博客平台、CMS系统等中非常有用,因为它可以轻松地处理复杂和多级的分类结构。例如,一个商品可能属于“电子产品 > 手机 > Android手机”,或者一篇文章可能被归类到“科技 > AI > ...
无限级分类允许我们创建灵活且可扩展的结构,能够处理任意深度的子类别。在这种情况下,"无限级分类js菜单"指的是利用JavaScript来实现这种功能的前端技术。 在数据库设计中,无限级分类通常通过自引用关系来实现。...
"通用无限级分类的存储过程"指的是能够适用于多种场景,处理任意深度分类的存储过程集合。这样的存储过程通常包括以下三个主要功能: 1. 插入:在分类系统中插入一个新的分类时,需要确保正确地维护其父分类关系。...
在网站开发中,数据分类是常见的需求,尤其在电商或者信息类网站中,商品或文章通常需要进行层次化的分类管理。无限级分类是一种能够解决这一问题的有效方式,它允许我们创建任意深度的分类结构,而不需要预先设定...
在PHP开发中,处理层级数据结构,如无限分类树,是一项常见的任务。这通常涉及到数据库中的类别表,其中每个类别可以有子类别,形成一个树状结构。在本篇文章中,我们将深入探讨如何使用PHP创建一个类来实现无限分类...