PHP无限分类(递归、非递归)

参考自:http://www.yuphp.org/Article/index/abId/41.html

 
什么是 PHP 无限分类呢,这就好比 Windows 下新建一个文件夹,在新建的文件夹下又可以新建一个文件夹,这样无限循环下去,无限分类也是这样,父类可以分出它子类,子类又可以分出它的子类,这样一直无限循环下去。
 
常见的无限分类主要有两种,一种是递归实现无线分类,另一种就是非递归实现无限分类。今天特将前一阵子写的无限分类贴出来供大家参考下。
 
详细代码如下:
 
<?php
 
/** Sql 代码
CREATE TABLE `yu_menu` (
  `id` smallint(5) unsigned NOT NULL auto_increment,
  `fid` smallint(5) unsigned default '0',
  `name` varchar(20) collate utf8_unicode_ci NOT NULL,
  `path` varchar(150) collate utf8_unicode_ci NOT NULL,
  `grade` tinyint(3) unsigned default '0',
  PRIMARY KEY  (`id`),
  KEY `fid` (`fid`,`name`,`path`,`grade`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='菜单测试表' AUTO_INCREMENT=15 ;
 
INSERT INTO `yu_menu` VALUES (1, 0, 'PHP函数', '0', 12);
INSERT INTO `yu_menu` VALUES (2, 0, 'PHP技术', '0', 98);
INSERT INTO `yu_menu` VALUES (3, 0, 'YuPHP', '0', 168);
INSERT INTO `yu_menu` VALUES (4, 0, 'PHP其它', '0', 2);
INSERT INTO `yu_menu` VALUES (5, 1, '正则函数', '0-1', 15);
INSERT INTO `yu_menu` VALUES (6, 5, 'Preg_match', '0-1-5', 5);
INSERT INTO `yu_menu` VALUES (7, 5, 'Preg_replace', '0-1-5', 45);
INSERT INTO `yu_menu` VALUES (8, 1, 'MySQL函数', '0-1', 45);
INSERT INTO `yu_menu` VALUES (10, 8, 'mysql_query', '0-1-8', 45);
INSERT INTO `yu_menu` VALUES (11, 8, 'mysql_set_chart', '0-1-8', 1);
INSERT INTO `yu_menu` VALUES (12, 2, '小偷程序', '0-2', 45);
INSERT INTO `yu_menu` VALUES (13, 2, '中文分词', '0-2', 84);
INSERT INTO `yu_menu` VALUES (14, 13, 'RMM分词', '0-2-13', 4);
 */
 
$conn = mysql_connect('localhost', 'root', 'root') or exit('服务器连接失败!');
mysql_select_db('test') or exit('数据库连接失败!');
mysql_set_charset('GBK', $conn);
 
$treeArr = array();
function getTree($fid = 0, $tier = 0) {
	global $treeArr;
	$sql = 'SELECT id, name FROM yu_menu WHERE fid = '.$fid.' ORDER BY grade DESC, id ASC';
	$resource = mysql_query($sql);
	while ($arr = mysql_fetch_assoc($resource)) {
		$treeArr[] = array($arr['id'], $arr['name'], $tier);
		getTree($arr['id'], ++$tier);
		$tier--;
	}
 
	return $treeArr;
}
 
function getMenu() {
	$sql = 'SELECT id, name, CONCAT(path, \'-\', id) AS newPath FROM yu_menu ORDER BY newPath ASC, grade DESC, id ASC';
	$resource = mysql_query($sql);
	while($arr = mysql_fetch_assoc($resource)) {
		$tier = count(explode('-', $arr['newPath'])) - 2;//主要是和上面保持一致
		$menuArr[] = array($arr['id'], $arr['name'], $tier);
	}
 
	return (empty($menuArr)) ? array() : $menuArr;
}
 
 
$treeArr = getTree();
//$treeArr = getMenu();
foreach ($treeArr as $value) {
	for ($i = 0; $i < $value[2]; $i++) {
		echo '&nbsp;&nbsp;&nbsp;&nbsp;';
	}
	echo $value[1].'-'.$value[0].'<br />';
}
 
@mysql_free_result($resource);
mysql_close($conn);
 
?>

下面是我稍微改了一下
其中递归部分最特别的应该是global的处理,之前写很多代码都是不允许用global的,于是就想着把$treeArr在方法里面传,不过那样越传越头疼

<?php
require_once 'class.database.php';
$db    =    new Database;
$db->connect('localhost', 'root', '','test1');
 
$treeArr = array();
function getTree($fid = 0, $tier = 0,$db)
{
    global $treeArr;   
    //最特别的应该是global的处理,之前写很多代码都是不允许用global的,于是就想着把¥treeArr在方法里面传,不过那样越传越头疼
    $sql     =     "SELECT id, name FROM yu_menu WHERE fid = '$fid' ORDER BY grade DESC, id ASC";
    $result    =    $db->fetchArrs($sql);
    if(!empty($result)&&$result!=false)
    {
        foreach ($result as $v)
        {
            $treeArr[] = array($v['id'], $v['name'], $tier);
            getTree($v['id'], ++$tier,$db);
            $tier--;       
        }
    }
    return $treeArr;
}
 
function getMenu() {
    $sql = 'SELECT id, name, CONCAT(path, \'-\', id) AS newPath FROM yu_menu ORDER BY newPath ASC, grade DESC, id ASC';
    $resource = mysql_query($sql);
    while($arr = mysql_fetch_assoc($resource)) {
        $tier = count(explode('-', $arr['newPath'])) - 2;//主要是和上面保持一致
        $menuArr[] = array($arr['id'], $arr['name'], $tier);
    }
 
    return (empty($menuArr)) ? array() : $menuArr;
}
 
 
$treeArr = getTree(0,0,$db);
//$treeArr = getMenu();
//var_dump($treeArr);
foreach ($treeArr as $value) {
    for ($i = 0; $i < $value[2]; $i++) {
        echo '&nbsp;&nbsp;&nbsp;&nbsp;';
    }
    echo $value[1].'-'.$value[0].'<br />';
}

Related posts:

Leave a Reply

Your email address will not be published.