我的功能比较庞大(一个专题功能中的无限个页面),先说下详细再看代码。
topic_info(基础表),topic_page(页面表)
基础表结构
CREATE TABLE `topic_info` ( `t_id` int(11) NOT NULL AUTO_INCREMENT, `t_name` varchar(30) NOT NULL, `t_start_date` date NOT NULL COMMENT '开始时间', `t_end_date` date NOT NULL COMMENT '结束时间', `t_keyword` varchar(120) NOT NULL COMMENT '键字关', `t_description` varchar(200) NOT NULL COMMENT '述描', `t_list_logo` varchar(150) NOT NULL COMMENT '列表小图标', `t_overview` varchar(255) NOT NULL, `t_urlname` varchar(10) NOT NULL COMMENT '专题url', `t_template_dir` varchar(15) NOT NULL COMMENT '模板文件夹名称', `t_sort` int(11) NOT NULL DEFAULT '100' COMMENT '排序,数字越小排月前', `t_doc` varchar(200) NOT NULL COMMENT '出入境相关文档', `mana_id` int(11) NOT NULL COMMENT '作者', `last_change_time` datetime NOT NULL COMMENT '后最修改人', `last_change_mana_id` int(11) NOT NULL COMMENT '最后修改时间', PRIMARY KEY (`t_id`) ) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='专题列表'
页面表结构
CREATE TABLE `topic_page` ( `p_id` int(11) NOT NULL AUTO_INCREMENT, `p_title` varchar(100) NOT NULL, `p_overview` varchar(255) NOT NULL COMMENT '一段小描述可以为空', `p_temp_name` varchar(30) NOT NULL COMMENT '模板名', `p_index` tinyint(1) NOT NULL DEFAULT '0' COMMENT '如果为1,就是首页,同一个t_id里只允许有一个', `p_sort` int(11) NOT NULL DEFAULT '100' COMMENT '排序,1最前', `father_p_id` int(11) NOT NULL COMMENT '上级id', `mana_id` int(11) NOT NULL, `last_change_time` datetime NOT NULL, `last_change_mana_id` int(11) NOT NULL, `t_id` int(11) NOT NULL COMMENT '所属专题', `p_menu_show` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1可见,0不可见', PRIMARY KEY (`p_id`) ) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
其实接下来的程序中,并不会过多的使用到基础表,但也放出来,给大家了解下为什么接下来会有t_id这些非topic_page表的东西。
程序部分用的是Thinkphp2.1,懒的脱离出来用原始php写了,大家有一定php基础的人一定看得懂这种封装。
但有一点必须注意:
这里的递归最好用class,因为单纯的function无法满足,有bug(php的bug)。
//控制器 public function index() { $id = intval ( $_GET ['id'] ); $this->assign ( "t_id", $id ); $page = $_POST ['pageNum'] > '0' ? intval ( $_POST ['pageNum'] ) - 1 : 0; $numPerPage = intval ( $_POST ['numPerPage'] ) == '0' ? 20 : intval ( $_POST ['numPerPage'] ); $page = $page * $numPerPage; $this->assign ( 'totalCount', $this->pageModel->getList ( true, 0, 0, "t_id = " . $id ) ); //计算总数 $this->assign ( 'currentPage', $_POST ['pageNum'] ); //当前页 $list = $this->pageModel->where ( 'father_p_id = 0' )->order ( 'p_sort asc' )->select (); $html = ''; foreach ( $list as $k => $v ) { $html .= ""; //通过这个函数递归获迭代数组 $html .= $this->pageModel->getSonList ( $v ); } $this->assign ( "html", $html ); $this->display ( "topic:page_control" ); } {$v['p_id']} "; if ($v ['p_index'] === 1) { $html .= '[主页面]'; } $html .= "{$v['p_title']} {$v['label_count']} {$v['p_temp_name']} " . D ( 'user.admin' )->getName ( $v ['mana_id'] ) . " {$v['last_change_time']} " . D ( 'user.admin' )->getName ( $v ['last_change_mana_id'] ) . "
//控制器里用到的$this->pageModel模型部分代码: /** * 获取所有p_id的子页面,并递归这些子页面的子子页面直到没有为止,并组成HTML * @param $array */ public function getSonList($array) { // $temp_list = $this->field ( 't_id,father_p_id,p_id,p_title,p_temp_name,p_sort' )->where ( 'father_p_id = ' . $array ['p_id'] )->order ( 'p_sort asc' )->select (); //如果有子页面数据,则递归函数,直到拿到所有的子页面为止 if (count ( $temp_list ) > 0) { foreach ( $temp_list as $temp_k => $temp_v ) { //用于存储当前页面的子页面总数 //因为当前页面也有可能是子页面,所以需要向上抓取。 //通过当前数据的父页面字段father_p_id不断往上递归,并记录递归次数 $this->getPPCount ( $temp_v ['father_p_id'], $temp_v ['p_id'] ); //将当前子页面的数据组织成html $html .= ""; //递归,因为程序有理由认为子页面还有其他子页面 $html .= $this->getSonList ( $temp_v ); } return $html; } } /** * 获取p_id的子页面总数 * @param $p_id * @param $num 第一次进来肯定是距离为1 */ private function getPPCount($father_p_id, $p_id, $getNum = 1) { if (! $p_id) return false; ///通过$p_id(本身是别人的fahter_p_id),获得其他使用它作为$father_p_id的值,如果有,就递归继续查询。 $result = $this->where ( 'p_id = ' . $father_p_id )->find (); if ($result ['father_p_id'] != 0) { $this->getPPCount ( $result ['father_p_id'], $result ['p_id'], $getNum + 1 ); } else { $this->pageToFatherCount = $getNum; } } {$temp_v['p_id']} "; for($i = 0; $i < $this->pageToFatherCount; $i ++) { $html .= " "; } $html .= "{$temp_v['p_title']} {$temp_v['label_count']} {$temp_v['p_temp_name']} " . D ( 'user.admin' )->getName ( $temp_v ['mana_id'] ) . " {$temp_v['last_change_time']} " . D ( 'user.admin' )->getName ( $temp_v ['last_change_mana_id'] ) . "
程序中一共递归了2处,值得一提的是getPPCount()模型方法里的那次递归,引发了一个bug。
如果直接return $getNum,值为null。
而且global $getNum也无效,所以不是局部变量或全局变量的问题。
只有通过赋值给类成员才可用。
至于变量引用这个方法我没试,觉得这样比用类成员解决问题更不靠谱。
所以这样已经是最好的办法了。
发表回复