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 />';
}

10 php目录文件操作类

<?php
/*
 * 从网上找的目录文件操作类
 * 在最底下写了实例,可以一个一个单独的测试
 */
	class file_dir
	{
		function check_exist($filename)		//检查目录或文件是否存在
		{
			if(file_exists($filename))
			{
				return true;
			}
			else	return false;
		}
 
		function create_dir($dirname,$mode=0777)	// 一次只能创建一级目录
		{
			if(is_null($dirname) || $dirname=="")	return false;
			if(!is_dir($dirname))
			{
				return mkdir($dirname,$mode);
			}
		}
 
		function createDir($aimUrl)		//可同时创建多级目录
		{
        	$aimUrl = str_replace('\\', '/', $aimUrl);
        	$aimDir = '';
        	$arr = explode('/', $aimUrl);
        	foreach ($arr as $str)
        	{
            	$aimDir .= $str . '/';
            	if (!file_exists($aimDir))
            	{
                	mkdir($aimDir);
            	}
        	}
    	}
 
		function delete_dir($dirname)		//删除目录
		{
			if($this->check_exist($dirname) and is_dir($dirname))
			{
				if(!$dirhandle=opendir($dirname)) return false;
				while(($file=readdir($dirhandle))!==false)
				{
					if($file=="." or $file=="..")	continue;
					$file=$dirname.DIRECTORY_SEPARATOR.$file;  //表示$file是$dir的子目录
					if(is_dir($file))
					{
						$this->delete_dir($file);
					}
					else
					{
						unlink($file);
					}
				}
				closedir($dirhandle);
				return rmdir($dirname);
			}
			else	return false;
		}
 
		function copy_dir($dirfrom,$dirto)		//复制目录
		{
			if(!is_dir($dirfrom))	return false;
			if(!is_dir($dirto))		mkdir($dirto);
			$dirhandle=opendir($dirfrom);
			if($dirhandle)
			{
				while(false!==($file=readdir($dirhandle)))
				{
					if($file=="." or $file=="..")	continue;
					$filefrom=$dirfrom.DIRECTORY_SEPARATOR.$file;  //表示$file是$dir的子目录
					$fileto=$dirto.DIRECTORY_SEPARATOR.$file;
					if(is_dir($filefrom))
					{
						$this->copy_dir($filefrom,$fileto);
					}
					else
					{	if(!file_exists($fileto))
						copy($filefrom,$fileto);
					}
				}
			}
			closedir($dirhandle);
		}
 
		function getdir_size($dirname)		//获取目录大小
		{
			if(!file_exists($dirname) or !is_dir($dirname))	 return false;
			if(!$handle=opendir($dirname)) 	return false;
			$size=0;
			while(false!==($file=readdir($handle)))
			{
				if($file=="." or $file=="..")	continue;
				$file=$dirname."/".$file;
				if(is_dir($file))
				{
					$size+=$this->getdir_size($file);
				}
				else
				{
					$size+=filesize($file);
				}
 
			}
			closedir($handle);
			return $size;
		}
 
		function getReal_size($size)	   // 单位自动转换函数
		{
			$kb=1024;
			$mb=$kb*1024;
			$gb=$mb*1024;
			$tb=$gb*1024;
			if($size<$kb)	return $size."B";
			if($size>=$kb and $size<$mb)	return round($size/$kb,2)."KB";
			if($size>=$mb and $size<$gb)	return round($size/$mb,2)."MB";
			if($size>=$gb and $size<$tb)	return round($size/$gb,2)."GB";
			if($size>=$tb)	return round($size/$tb,2)."TB";
		}
 
		function copy_file($srcfile,$dstfile)
		{
			if(is_file($srcfile))
			{
				if(!file_exists($dstfile))
				return copy($srcfile,$dstfile);
			}
			else	return false;
		}
 
   	 	function unlink_file($filename)		//删除文件
   	 	{
   	 		if($this->check_exist($filename) and is_file($filename))
   	 		{
   	 			return unlink($filename);
   	 		}
   	 		else	return false;
   	 	}
 
   	 	function getsuffix($filename)			//获取文件名后缀
   	 	{
   	 		if(file_exists($filename) and is_file($filename))
   	 		{
   	 			return end(explode(".",$filename));
   	 		}
   	 	}
 
   	 	function input_content($filename,$str)		//将字符串写入文件
   	 	{
   	 		if(function_exists('file_put_contents'))
   	 		{
   	 			file_put_contents($filename,$str);
   	 		}
   	 		else
   	 		{
   	 			$fp=fopen($filename,"wb");
   	 			fwrite($fp,$str);
   	 			fclose($fp);
   	 		}
   	 	}
 
   	 	function output_content($filename)			//将整个文件内容读出到一个字符串中
   	 	{
   	 		if(function_exists('file_get_contents'))
   	 		{
   	 			return file_get_contents($filename);
   	 		}
   	 		else
   	 		{
   	 			$fp=fopen($filename,"rb");
   	 			$str=fread($fp,filesize($filename));
   	 			fclose($fp);
   	 			return $str;
   	 		}
   	 	}
 
   	 	function output_to_array($filename)		//将文件内容读出到一个数组中
   	 	{
   	 		$file=file($filename);
   	 		$arr=array();
   	 		foreach($file as $value)
   	 		{
   	 			$arr[]=trim($value);
   	 		}
   	 		return $arr;
   	 	}
 
 
	}
$dir=new file_dir;
 
$para	=	'<br />----------------------------------------------------------------------<br />';
 
echo $dir->check_exist("D:/wamp/www/test2/");echo $para;
echo $dir->create_dir("D:/wamp/www/test2/");echo $para;
echo $dir->createDir("D:/wamp/www/test2/test/");echo $para;
echo $dir->delete_dir("D:/wamp/www/test2/test/");echo $para;
echo $dir->copy_dir("D:/wamp/www/test/","D:/wamp/www/test3/");echo $para;
echo $size	=	$dir->getdir_size("D:/wamp/www/test3/");echo $para;
echo $dir->getReal_size($size);echo $para;
 
echo $dir->copy_file("D:/wamp/www/test3/fenlei.php","D:/wamp/www/test3/fenlei2.php");echo $para;
echo $dir->unlink_file("D:/wamp/www/test3/fenlei.php");echo $para;
echo $dir->getsuffix("D:/wamp/www/test3/fenlei2.php");echo $para;
echo $dir->input_content("D:/wamp/www/test3/fenlei5.php",'test');echo $para;
echo $dir->output_content("D:/wamp/www/test3/fenlei3.php");echo $para;
$outPut	=	$dir->output_to_array("D:/wamp/www/test3/fenlei3.php");echo $para;
print_r($outPut);
?>

列出所有的目录和文件(使用了递归readdir等函数)

function file_list($path)
{
	if ($handle = opendir($path)) 
	{
		while (false !== ($file = readdir($handle))) 
		{
			if ($file != "." && $file != "..") 
			{
				if (is_dir($path."/".$file)) 
				{
					echo $path.": ".$file."<br>";
					file_list($path."/".$file);
				} 
				else 
				{
					echo $path.": ".$file."<br>";
				}
			}
		}
	}
}
file_list('D:/wamp/www');