实现无限级分类通常只用一个数据表,一般可经过递归和非递归两种方法来实现。递归方法必须使用递归 php
调用方式才能进行数据遍历,删除等操做,因此须要发送屡次查询数据库语句,很是影响执行效率。那么 html
非递归该怎样来实现无限分类呢?简单来讲可用一张表四个字段和一条语句来实现。
一、一张表四个字段
DROP TABLE IF EXISTS `wb_columns`;
CREATE TABLE `eway_columns` (
`colId` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`colPid` smallint(5) unsigned NOT NULL DEFAULT '0',
`colPath` varchar(100) NOT NULL DEFAULT '',
`colTitle` varchar(100) NOT NULL DEFAULT '',
PRIMARY KEY (`colId`),
KEY `colPath` (`colPath`)
) ENGINE=MyISAM CHARSET=utf8; web
二、一条语句
SELECT concat(colPath,'-',colId) AS bpath, colId,colPid,colPath, colTitle, FROM " . C thinkphp
('DB_PREFIX') . "columns ORDER BY bpath, colId;
在上面的一条语句的SQL查询中,使用MYSQL中的concat函数将colPath和colId字段经过字符"-"链接起来 数据库
,并将该字段设置为bpath别名。而后先经过bpathpb 字段进行排序,若是有相同的路径再经过colId字段 函数
进行排序,这样就会以分类的各级层次结构将结果返回。
下面是在thinkphp3.1中非递归无限级分类的实现代码
<?php
/**
* 分类Columns的控制器ColumnsAction.class.php
*/
class ColumnsAction extends Action{
//分类列表
public function index(){
$catarray=$this->Catlist();
$this->assign('catarray',$catarray);
$this->display();
}
//分类添加表单
public function insert() {
$catarray=$this->Catlist();
$this->assign('catarray',$catarray);
$this->display();
}
public function add() {
$D = D($module);
if ($vo = $D->create()) {//由于使用模型类处理,自动完成必须经过create方法才能生效。
$list = $D->add();
if ($list !==false) {
$this->success("添加成功");
} else {
$this->error('添加失败');
}
} else {
$this->error($D->getError());
}
}
//实现树型层级的分类
function Catlist() {
$Columns = new Model;
$Module = M("News");
$list = $Columns->query("SELECT concat(colPath,'-',colId) AS bpath, this
colId,colPid,colPath, colTitle, FROM " . C('DB_PREFIX') . "columns ORDER BY bpath, colId");
foreach ($list as $k => $v) {
$list[$k]['count'] = count(explode('-', $v['bpath']));
$list[$k]['total'] = $Module->where('catid=' . $v['colId'])->count();
$str = '';
if ($v['colPid'] <> 0) {
for ($i = 0; $i < $list[$k]['count'] * 2; $i++) {
$str .= ' ';
}
$str .= '|-';
}
$list[$k]['space'] = $str;
}
return $list;
}
/**
* 分类Columns的模型类ColumnsModel.class.php
* 做用:在添加分类或修改分类时自动处理colPath字段并保存到数据库中
* callback :回调方法 ,表示填充的内容是一个当前模型的方法
* Model:: MODEL_INSERT 或者1新增数据时候验证
* Model:: MODEL_UPDATE 或者2编辑数据时候验证
* Model:: MODEL_BOTH 或者3 所有状况下验证(默认),这里选择该验证。
*/
<?php
class ColumnsModel extends Model{
protected $_auto=array(//thinkphp的自动填充
array('colPath','colPath',3,'callback'),
);
function colPath(){
$colPid=isset($_POST['colPid'])?(int)$_POST['colPid']:0;
$colId=$_POST['colId'];
if($colPid==0){
return 0;
}
$fat=$this->where('colId='.$colPid)->find();//查询的是父级ID
$data=$fat['colPath'].'-'.$fat['colId'];//获得父级的colPath,连上父级ID,返回的 spa
是子级的colPath
return $data;
}
} htm
须要注意的是,这是使用模型的自动完成功能,因此必须经过create方法才能生效,Create方法建立的数 对象
据对象是保存在内存中,并无实际写入到数据库中,直到使用add方法才真正写入数据库中。
完整的实例下载WBlog博客程序。
本文首发网志博客,欢迎转载!转载请注明本文地址,谢谢。
本文地址:http://www.w3note.com/web/32.html