[转] PHP 实现无限目录分级
2010-06-18 17:43
363 查看
这几天好忙,都没时间写点东西了,今天中午抽点时间,写个 无限目录分级 吧!
好吧,就不耽误时间了,直接来步骤
第一步,首先肯定是要建一个存放目录的表了,表怎么录入数据的,我就不说了。我用的是mysql数据库
我把表放在test数据库里,你们可以随便,但记得改下面我贴的代码里面的数据库名
CREATE TABLE IF NOT EXISTS `node` (
`id` int(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '栏目名',
`p_id` int(8) NOT NULL COMMENT '父结点',
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=14 ;
--
-- 导出表中的数据 `node`
--
INSERT INTO `node` (`id`, `name`, `p_id`) VALUES
(1, '第一级 1', 0),
(2, '第一级 2', 0),
(3, '第一级 3', 0),
(4, '第一级 4', 0),
(5, '第二级 1-1', 1),
(6, '第二级 1-2', 1),
(7, '第二级 2-1', 2),
(8, '第二级 2-2', 2),
(9, '第二级 3-1', 3),
(10, '第二级 4-1', 4),
(11, '第三级 1-1-1', 5),
(12, '第三级 1-1-2', 6),
(13, '第三级 2-1-1', 7);
把以上的代码,复制粘贴成 node.sql ,在导入数据库,怎么导入的,我也不说了,真的不会的话,就在网上找一下吧,改天再写个贴,关于mysql操作的吧
第二步,就是要写代码了,我自己都已经写好了,也测试过了,可以运行!把代码贴上吧!
就叫 test.php吧 直接把数据全部提取出来,然后再进行处理
<?php
$conn = mysql_connect( 'localhost', 'root', '111111' ); //用户名和密码改成自己相应的
mysql_select_db( 'test', $conn ); //数据库也是的,改成自己的
mysql_query("set names 'utf8'");
$sql = "select id, name,p_id from node"; //表的名字如果没有动的话,这里就不要动了
$query = mysql_query( $sql );
$level = 0;
while( $rs = mysql_fetch_array( $query ) )
{
$rs['isChild'] = '';
$group[] = $rs; //把所有数据都保存到 $group 里,然后进行处理
}
// 下面这二个函数进行处理
/**
* 判断节点是否有子节点
*
* @param array $arr 要序列化的数组
* @param int $pid 节点ID
* @return boolean
*/
function existsChild($arr, $pid)
{
foreach ($arr as $val)
{
if($val['p_id'] == $pid)
{
return true;
}
}
return false;
}
/**
* 序列化树
*
* @param array $arr 要序列化的数组
* @param int $pid 第一层父类ID,我这时初始化为0
* @param int $repeat 分级间隔
* @return array
*/
function getClass($arr, $pid = 0, $repeat = 0)
{
foreach ($arr as $key => $val)
{
if($val['p_id'] == $pid)
{
$arrChild = array();
if($pid != 0)
{
$repeat++;
}
$str = str_repeat(' ', $repeat);
$arr[$key]['isChild'] = $str;
$array[] = $arr[$key];
if(existsChild($arr, $val['id']))
{
$arrChild = getClass($arr, $val['id'], $repeat);
}
$array = array_merge($array, $arrChild);
if($pid != 0)
{
$repeat--;
}
}
}
if(!is_array($array))
{
return array();
}
return $array;
}
?>
然后
$arrTree = getClass($group); //这就OK了
然后打印出 $arrTree 就可以了!
<!-- 下面这段js是实现子目录的开关状态的 -->
<script type="text/javascript">
function opennode( id )
{
if( document.getElementById( id ).style.display == 'none' )
{
document.getElementById( id ).style.display = 'block';
}
else
{
document.getElementById( id ).style.display = 'none';
}
}
</script>
<style type="text/css">
<!--
a:link {
text-decoration: none;
}
a:visited {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:active {
text-decoration: none;
}
-->
</style>
忘了说了,我用的是国际标准编码utf-8,如果不想用utf-8的话,1. 需要在第一步里把表的编码改为你想要用的编码。 2. 在第二步里把页面编码统一为你想用的编码。 但强调一点,要保持编码统一!
运行一下,如果不出意思的话,应该是OK的。
如果还不行的话,可以加我blog里的QQ群,群里讨论...
好吧,就不耽误时间了,直接来步骤
第一步,首先肯定是要建一个存放目录的表了,表怎么录入数据的,我就不说了。我用的是mysql数据库
我把表放在test数据库里,你们可以随便,但记得改下面我贴的代码里面的数据库名
CREATE TABLE IF NOT EXISTS `node` (
`id` int(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '栏目名',
`p_id` int(8) NOT NULL COMMENT '父结点',
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=14 ;
--
-- 导出表中的数据 `node`
--
INSERT INTO `node` (`id`, `name`, `p_id`) VALUES
(1, '第一级 1', 0),
(2, '第一级 2', 0),
(3, '第一级 3', 0),
(4, '第一级 4', 0),
(5, '第二级 1-1', 1),
(6, '第二级 1-2', 1),
(7, '第二级 2-1', 2),
(8, '第二级 2-2', 2),
(9, '第二级 3-1', 3),
(10, '第二级 4-1', 4),
(11, '第三级 1-1-1', 5),
(12, '第三级 1-1-2', 6),
(13, '第三级 2-1-1', 7);
把以上的代码,复制粘贴成 node.sql ,在导入数据库,怎么导入的,我也不说了,真的不会的话,就在网上找一下吧,改天再写个贴,关于mysql操作的吧
第二步,就是要写代码了,我自己都已经写好了,也测试过了,可以运行!把代码贴上吧!
就叫 test.php吧 直接把数据全部提取出来,然后再进行处理
<?php
$conn = mysql_connect( 'localhost', 'root', '111111' ); //用户名和密码改成自己相应的
mysql_select_db( 'test', $conn ); //数据库也是的,改成自己的
mysql_query("set names 'utf8'");
$sql = "select id, name,p_id from node"; //表的名字如果没有动的话,这里就不要动了
$query = mysql_query( $sql );
$level = 0;
while( $rs = mysql_fetch_array( $query ) )
{
$rs['isChild'] = '';
$group[] = $rs; //把所有数据都保存到 $group 里,然后进行处理
}
// 下面这二个函数进行处理
/**
* 判断节点是否有子节点
*
* @param array $arr 要序列化的数组
* @param int $pid 节点ID
* @return boolean
*/
function existsChild($arr, $pid)
{
foreach ($arr as $val)
{
if($val['p_id'] == $pid)
{
return true;
}
}
return false;
}
/**
* 序列化树
*
* @param array $arr 要序列化的数组
* @param int $pid 第一层父类ID,我这时初始化为0
* @param int $repeat 分级间隔
* @return array
*/
function getClass($arr, $pid = 0, $repeat = 0)
{
foreach ($arr as $key => $val)
{
if($val['p_id'] == $pid)
{
$arrChild = array();
if($pid != 0)
{
$repeat++;
}
$str = str_repeat(' ', $repeat);
$arr[$key]['isChild'] = $str;
$array[] = $arr[$key];
if(existsChild($arr, $val['id']))
{
$arrChild = getClass($arr, $val['id'], $repeat);
}
$array = array_merge($array, $arrChild);
if($pid != 0)
{
$repeat--;
}
}
}
if(!is_array($array))
{
return array();
}
return $array;
}
?>
然后
$arrTree = getClass($group); //这就OK了
然后打印出 $arrTree 就可以了!
<!-- 下面这段js是实现子目录的开关状态的 -->
<script type="text/javascript">
function opennode( id )
{
if( document.getElementById( id ).style.display == 'none' )
{
document.getElementById( id ).style.display = 'block';
}
else
{
document.getElementById( id ).style.display = 'none';
}
}
</script>
<style type="text/css">
<!--
a:link {
text-decoration: none;
}
a:visited {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:active {
text-decoration: none;
}
-->
</style>
忘了说了,我用的是国际标准编码utf-8,如果不想用utf-8的话,1. 需要在第一步里把表的编码改为你想要用的编码。 2. 在第二步里把页面编码统一为你想用的编码。 但强调一点,要保持编码统一!
运行一下,如果不出意思的话,应该是OK的。
如果还不行的话,可以加我blog里的QQ群,群里讨论...
相关文章推荐
- PHP 实现无限目录分级
- php实现select无限分级下拉
- PHP不用递归实现无限分级的例子分享
- PHP不用递归实现无限分级的例子分享
- 利用php递归实现无限分类 格式化数组的详解
- PHP实现遍历、复制、删除目录
- C语言实现的统计php代码行数功能源码(支持文件夹、多目录)
- 存储过程+数据缓存版的TreeView控件“无限”分级实现
- php清空(删除)指定目录下的文件,不删除目录文件夹的实现代码
- asp.net中用TreeView控件的TreeNodePopulate事件实现无限分级的好办法
- JQ 实现无限分级导航菜单
- PHP实现无限级分类(不使用递归)
- php无限分级
- php实现无限级分类查询(递归、非递归)
- php 递归 实现无限分类 格式化数组
- php实现目录及目录文件下的遍历
- php实例分享之通过递归实现删除目录下的所有文件详解
- php实现无限级分类查询(递归、非递归)
- PHP 无限分类实现程序
- php+mysql实现无限级分类