会员
周边
众包
新闻
博问
闪存
赞助商
Chat2DB
所有博客
当前博客
我的博客
我的园子
账号设置
会员中心
简洁模式
...
退出登录
注册
登录
首页
订阅
管理
[php]数组法生成tree-〉完全独立,包含完整数据版
<html> <head> <title>数组法生成tree-〉完全独立,包含完整数据版</title> <link rel="stylesheet" href="base.css" type="text/css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head> <style> body { scrollbar-base-color:#517CEA;scrollbar-arrow-color:#FFFFFF; } *{line-height:1;margin:0px;PADDING:0px;} </style> <body bgcolor="#FFFFFF"> <pre> <? //require_once("echo.php"); /** * 共计查找数据库两次,使用CONCAT_WS函数1次 * 使用正则搜数组一次(N条记录)*N次(N*X条记录)*(N*X)次(Y条记录,依次类推)。 * 对于2级类,则是 2数据库+1*N次正则。 * 如果用数据库,则是1数据库 * N次数据库。 * 如果用数组遍历,则是1数据库(Y条记录)+N*Y+(Y-N)次数组循环。 * 如果用字符串,将所有记录穿成一个字符串,然后用正则递归搜,将面临搜到字串后要分割字串的问题。 * 用字符串迭代搜效率要低10倍。 * * 不知道哪个效率更高。不过我想,无论如何从内存搜应该比从数据库里搜要快吧 * 而内存中搜,用正则和数组遍历的比较。对于大记录数组遍历的循环次数将会恐怖地增长。 * 然而我不知道preg_grep在数组中搜索是否和普通数组循环一样。如果是,那么。二者恐怕效率差不多。 * * 比较字符串搜索,数组的效率要高出10倍。27条记录(6x4),。1000次/4秒2005-12-29。 * 其中从数据库取记录+类初始化用了0.004秒时间。而实际执行一次遍历的时间约与此相等0.004秒。 * 预计下个版本将+上数据库版本判断功能,增加生成select框的函数。 * 2005-12-29 */ $config=array( "host"=>'localhost', "dbUser"=>'root', "dbPass"=>'', "db"=>'mambog_corp', "tbl"=>'mos_collector_menu', //表名 "encode"=>"UTF8", //数据表数据的编码默认是utf8,没有横线,如果表中数据是其他编码,请自行填写,如果不填,绝对乱码 "id"=>'id', //主id的字段名,这里就是id "pid"=>'pid', //父id的字段名,这里就是pid. "where"=>'', //过滤条件。 "dim"=>'_', // 分割的字符,连接字段的分割符,从数据库里取记录时要用,用preg_grep正则搜索时要用。 "topid"=>0 //从哪个层次开始,从哪个类别层开始。一般父类为0的是顶级类别 ); //时间开始 //$timeStart = getmicrotime(); $tree = new TreeMenu; $tree->config=$config; //开始生成树 $tree->start(); echo $tree->menu; //时间结束 //echo (getmicrotime()-$timeStart)."<br/>"; //这个类 class database{ function connect( $host='localhost', $user, $pass, $db , $encode="UTF8" ) { // perform a number of fatality checks, then die gracefully if (!function_exists( 'mysql_connect' )) { echo "dbconnect error<br/> check your mysql server"; exit(); } if (!($this->_resource = @mysql_connect( $host, $user, $pass ))) { die( 'FATAL ERROR: Connection to database server failed.' ); } if (!mysql_select_db($db)) { die( "FATAL ERROR: Database not found. Operation failed with error: ".mysql_error()); } $q = "set names ".$encode; $this->setQuery($q); $this->query(); } // end func function setQuery( $sql) { $sql = trim( $sql ); $this->_sql = $sql; }//end func function query() { $this->_cursor = mysql_query( $this->_sql, $this->_resource ); if (!$this->_cursor) { echo mysql_errno( $this->_resource ); echo mysql_error( $this->_resource )." SQL=$this->_sql"; return false; } return $this->_cursor; }//end func /** * Load an array of single field results into an array */ function loadResultArray($numinarray = 0 ,$indexKey='',$valueKey='') { if (!($cur = $this->query())) { return null; } $array = array(); /* 生成数组的key */ if ($indexKey && $valueKey) { while ($row = mysql_fetch_assoc( $cur )) { $array[$row[$indexKey]] = $row[$valueKey]; } }else{ while ($row = mysql_fetch_row( $cur )) { $array[] = $row[$numinarray]; } } mysql_free_result( $cur ); return $array; } /** * Load a assoc list of database rows * @param string The field name of a primary key * @return array If <var>key</var> is empty as sequential list of returned records. */ function loadAssocList( $key='' ) { if (!($cur = $this->query())) { return null; } $array = array(); while ($row = mysql_fetch_assoc( $cur )) { if ($key) { $array[$row[$key]] = $row; } else { $array[] = $row; } } mysql_free_result( $cur ); return $array; }//end func }//end class class TreeMenu extends database{ /* 连接数据库和表的配置 */ var $config=array( "host"=>'localhost', "dbUser"=>'root', "dbPass"=>'', "db"=>'', "tbl"=>'', //表名 "encode"=>"UTF8", //数据表数据的编码 "id"=>'id', //主id的字段名,这里就是id "pid"=>'pid', //父id的字段名,这里就是pid. "where"=>'', //过滤条件。 "dim"=>'_', // 分割的字符,连接字段的分割符,从数据库里取记录时要用,用preg_grep正则搜索时要用。 "topid"=>0 //从哪个层次开始,从哪个类别层开始。一般父类为0的是顶级类别 ); var $rowsIndex=array(); var $rows = array(); var $menu='┌◎\n'; /* 得到类别字符串 */ function genTreeArray(){ $tbl = $this->config['tbl']; $id = $this->config['id']; $pid = $this->config['pid']; $dim = $this->config['dim']; $where = $this->config['where']; $q = "select CONCAT_WS( '$dim', $id , $pid) as indexKey , $tbl.* from $tbl $where "; //echot($q); $this->setQuery($q); $this->rowsIndex = $this->loadResultArray(0,$id,'indexKey');//prt($rowsIndex); $this->rows = $this->loadAssocList( 'indexKey'); //prt($rows); } /* 开始执行 */ function start(){ /* 连接数据库 */ $this->connect( $this->config['host'], $this->config['dbUser'], $this->config['dbPass'], $this->config['db'],$this->config['encode'] ); /* 初始生成类别数组 */ $this->genTreeArray(); /* 搜出所有的$topid下的类别 */ $reg = "#([0-9]+)".$this->config['dim'].$this->config['topid']."#i"; $mainIndex=preg_grep($reg,$this->rowsIndex); //prt($mainIndex); if (count($mainIndex)==0) { return; } /* 开始生成类别树字串 */ $this->menu="┌◎\n"; $this->getTreeMenuStr(0,0,0,$mainIndex); }//end func start /* 生成菜单字符串,存入this->menu */ function getTreeMenuStr($pid=0,$level=0,$blanklevel=0,&$mainIndex){ $pre=""; for ($k=0;$k<$level ;$k++ ) { $pre .="│";//echot($level); } for ($k=0;$k<$blanklevel ;$k++ ) { $pre .=" ";//echot($level); } /* 控制 */ $totmain = count($mainIndex)-1; $toti=0; /* 为每一个顶级类别找出其子类别 ├┬*/ foreach ($mainIndex as $mkey=>$vk) { $nextlevel = $level; $link = "<a href='".$this->rows[$vk][link]."' >"; $title = $this->rows[$vk]['title']; /* 在索引数组里找出下级类别 */ $reg = "#([0-9]+)".$this->config['dim'].$mkey."#i"; $subIndex=preg_grep($reg,$this->rowsIndex); //prt($subIndex); $totsub = count($subIndex); if ($toti<$totmain) { $this->menu .=$pre.'├'.$title."\n"; } else { $this->menu .=$pre.'└'.$title."\n"; } if ($totsub>0) { if ($toti<$totmain) { $nextlevel=$level+1; } else { $blanklevel++; } $this->getTreeMenuStr($mkey,$nextlevel,$blanklevel,$subIndex); } $toti++; }//foreach //$this->menu .=$pre."└◎\n"; }//end func }//end class /** 数据表结构 -- phpMyAdmin SQL Dump -- version 2.6.3-rc1 -- http://www.phpmyadmin.net -- -- 主机: localhost -- 生成日期: 2005 年 12 月 28 日 10:41 -- 服务器版本: 4.1.11 -- PHP 版本: 5.0.5 -- -- 数据库: `mambog_corp` -- -- -- 表的结构 `mos_collector_menu` -- DROP TABLE IF EXISTS `mos_collector_menu`; CREATE TABLE IF NOT EXISTS `mos_collector_menu` ( `id` int(11) NOT NULL auto_increment, `pid` int(11) NOT NULL default '0', `title` varchar(50) NOT NULL default '', `link` varchar(255) NOT NULL default '', `published` tinyint(1) NOT NULL default '0', `ordering` int(11) NOT NULL default '0', `access` tinyint(3) unsigned NOT NULL default '0', `params` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=94 ; -- -- 导出表中的数据 `mos_collector_menu` -- INSERT INTO `mos_collector_menu` VALUES (66, 0, '<a href="#" target="_parent">退出DEDECMS</a>', '#', 1, 0, 0, ''), (67, 0, '频道管理', '#', 1, 0, 0, ''), (68, 67, '板块模板管理', '../web_type_web.php', 1, 0, 0, ''), (69, 67, '通用模板管理', '../file_view.php?activepath=<?=$mod_dir?>', 1, 0, 0, ''), (70, 67, '主页创建向导', '../add_home_page.php', 1, 0, 0, ''), (71, 0, '内容维护', '#', 1, 0, 0, ''), (72, 71, '待审核文章', '../list_news_member.php', 1, 0, 0, ''), (73, 71, '专题管理', '../list_news_spec.php', 1, 0, 0, ''), (74, 71, '评论管理', '../list_feedback.php', 1, 0, 0, ''), (75, 0, '内容发布', '#', 1, 0, 0, ''), (76, 75, '专题创建向导', '../add_news_spec.php', 1, 0, 0, ''), (77, 75, '图集发布向导', '../add_news_pic.php', 1, 0, 0, ''), (78, 75, '软件发布向导', '../add_news_soft.php', 1, 0, 0, ''), (79, 75, 'Flash向导', '../add_news_flash.php', 1, 0, 0, ''), (80, 0, '附助功能', '#', 1, 0, 0, ''), (81, 80, '友情链接管理', '../add_friendlink.php', 1, 0, 0, ''), (82, 80, '投票管理', '../add_vote.php', 1, 0, 0, ''), (83, 80, '论坛扩展', '../bbs_addons.php', 1, 0, 0, ''), (84, 80, '留言簿管理', '<?=$art_php_dir?>/guestbook/index.php', 1, 0, 0, ''), (85, 0, '会员管理', '#', 1, 0, 0, ''), (86, 85, '网上会员管理', '../list_user.php', 1, 0, 0, ''), (87, 0, '文件管理', '#', 1, 0, 0, ''), (88, 87, '文件浏览器', '../file_view.php', 1, 0, 0, ''), (89, 0, '数据库管理', '#', 1, 0, 0, ''), (90, 89, '数据备份/还原', '../sys_back_data.php', 1, 0, 0, ''), (91, 89, 'MySQL命令', '../sys_domysql.php', 1, 0, 0, ''), (92, 0, '系统帮助', '#', 1, 0, 0, ''), (93, 92, '系统信息', '../blank.php', 1, 0, 0, ''); */ ?> </body> </html>
Posted on
2005-12-29 20:03
古代
阅读(
640
) 评论(
0
)
编辑
收藏
举报
刷新页面
返回顶部