澳门新葡亰娱乐官网php数组转换成树的几个例子

最近问无限分类的类树问题比较多,所以一高兴自己写了一个,我刚写完的,大家用用看,看看怎么实现起来更快,更简单,把你的树也贴出来(要只查询一次数据库的)br
这是一棵分类列表的类树, 支持无限分类br
一个分类下面可以同时有”包含子类的分类”和”最终分类”;br
唯一的优点是*****只需要进行一次的数据库*****查询.br
样子不是很好看,不过可以自定义修改,可以自己定义css加里面br
缓存方面还没有作,可以自己补上 下面例子的目录结构是这样的。
–Catagory.php br –images—-tree.jsp br –images—-treeopen.gif br
–images—-treeclose.gif br –images—-line.gif br
/****************tree.jsp********************/
function expand(id){ node = document.all(‘node’+id);
if(node.style.display==”){ node.style.display = ‘none’;
document.images(‘img’+id).src = imgopen; }else{ node.style.display = ”;
document.images(‘img’+id).src = imgclose; } }
/****************Catagory.php********************/
?php define(‘CATAGORY_TREE_EXPEND_NONE’,0);
define(‘CATAGORY_TREE_EXPEND_ALL’,1); class Catagory{ //基础分类数据
var $treeData = array();
//分类的等级结构数组,以分类的id值作为数组的关键字 var $treePList =
array(); //自分类对应上级类的关系 var $treeCList = array(); /* *
这个是大分类的模板 * * __id__ 分类的编号 * __name__
分类的名称 * __image__ 分类前面显示的图像名称 $imgOpen or $imgClose
* __open__ 分类当前是否是展开的 * __inner__ 子分类显示的位置
* 样式可以根据自己的需要任意修改 ,但是不能删除现有的元素 */ var
$blockTpl = ‘ table cellpadding=”0″ cellspacing=”0″ tr td colspan=”2″a
onclick=”expand(__id__); return false;” href=”#” img
src=”__image__” width=”15″ height=”15″ /a a
onclick=”expand(__id__); return false;” href=”#” __name__/a/td
/tr tr td width=”20″/tdtd__inner__/td /tr /table’; /* *
这个是小分类的模板 * * see $blockTpl */ var $elementTpl = ‘img
src=”images/line.gif” width=”15″ height=”15″a href=”?id=__id__”font
color=”white”__name__/font/abr/’; /* * 这个是当前位置显示模板 *
* see $blockTpl */ var $currentTpl = ‘a href=”?id=__id__”font
color=”white”__name__/font/a’; var $js = “images/tree.js”; var
$imgOpen = ‘images/treeopen.gif’; var $imgClose =
‘images/treeclose.gif’; var $imgLine = ‘images/line.gif’; var $cachFile
= ”; var $expand = 0; var $result = array(); var $treeStr = ”; var
$currentStr = ”; /* * 用来初始化,传入分类数据 * *param $data
array() */ function Catagory(&$data){ $this-_init($data); } function
_init($tmpData){ $plevel = $clevel = $treeData =
array();foreach($tmpData as $value){ $treeData[$value[‘id’]] =
$value; $plevel[$value[‘pid’]][$value[‘id’]] = ‘END’;
$clevel[$value[‘id’]] = $value[‘pid’]; } $this-treeData =
&$treeData; $this-treePList = &$plevel; $this-treeCList = &$clevel; }
/* * 解析分类列表 * *param $cataId int 要解析的主分类的编号 */
function parseNode($cataId=0){ $this-result =
$this-treePList[$cataId]; if($this-result==null) die(“Catagory id
error”); $this-treeStr = $this-_doNode($this-result); $this-treeStr .=
$this-_jsParse(); } function &_doNode(&$result){ $nstr = $estr = ”;
foreach($result as $key=$value){ if(isset($this-treePList[$key])){
$result[$key] = $this-treePList[$key]; $inner =
$this-_doNode($result[$key]); $nstr .= $this-_parseNodeTpl($key,
$inner); }else{ $estr .= $this-_parseElementTpl($key); } } return
$nstr.$estr; } function &_parseNodeTpl($cataId, $inner){ $data =
$this-treeData[$cataId]; $str = preg_replace(‘ __id__ ‘,
$data[‘id’], $this-blockTpl); $str = preg_replace(‘ __name__ ‘,
$data[‘name’], $str); $str = preg_replace(‘ __image__ ‘,
($this-expand? $this-imgClose:$this-imgOpen), $str); $str =
preg_replace(‘ __open__ ‘, ($this-expand?”:’none’), $str); $str =
preg_replace(‘ __inner__ ‘, $inner, $str); return $str; } function
_parseElementTpl($cataId){ $data = $this-treeData[$cataId]; $str =
preg_replace(‘ __id__ ‘, $data[‘id’], $this-elementTpl); $str =
preg_replace(‘ __name__ ‘, $data[‘name’], $str); $str =
preg_replace(‘ __image__ ‘, $this-imgLine, $str); return $str; }
function _jsParse(){ $str = “script language=/”javascript/” imgopen =
/”$this-imgOpen/”; imgclose = /”$this-imgClose/”; /scriptscript
src=/”$this-js/” language=/”javascript/”/script”; return $str; } /* *
展开分类$cataId * *param $cataId int 要展开的分类的编号 */ function
parseCurrent($cataId){ $str = ”; $str .=
$this-_parseCurrentTpl($cataId);
while(isset($this-treeCList[$cataId]) &&
$this-treeCList[$cataId]!=0){ $cataId = $this-treeCList[$cataId];
$str = $this-_parseCurrentTpl($cataId).’-‘.$str; } $this-currentStr =
&$str; } function _parseCurrentTpl($cataId){ $data =
$this-treeData[$cataId]; $str = preg_replace(‘ __id__ ‘,
$data[‘id’], $this-currentTpl); $str = preg_replace(‘ __name__ ‘,
$data[‘name’], $str); return $str; } /* * 解析当前分类的路径 *
*param $cataId int 要解析的主分类的编号 */ function expand($cataId){
if($this-expand0) return ; $str = ”;
if(isset($this-treePList[$cataId])) $str .= “expand($cataId);”;
while(isset($this-treeCList[$cataId]) &&
$this-treeCList[$cataId]!=0){ $str .=
“expand(“.$this-treeCList[$cataId].”);”; $cataId =
$this-treeCList[$cataId]; } $this-treeStr .= “script
language=/”javascript/”$str/script”; } /* * 返回当前分类的路径 */
function getCurrentStr(){return $this-currentStr; } /* *
返回分类的类树 */ function getTreeStr(){ return $this-treeStr; }
function setTpl($blockTpl, $elementTpl, $currentTpl, $js){
$this-blockTpl = $blockTpl; $this-elementTpl = $elementTpl;
$this-currentTpl = $currentTpl; $this-js = $js; } function
setImage($open, $close, $line){ $this-imgOpen = $open; $this-imgClose =
$close; $this-imgLine = $line; } function setExpend($expand){
$this-expand = $expand; } } //分类的基础数据的样子如下: $data =
array(array(‘id’=1, ‘name’=’name1’, ‘pid’=0, ‘order’=1), array(‘id’=2,
‘name’=’name2’, ‘pid’=1, ‘order’=1), array(‘id’=3, ‘name’=’name3’,
‘pid’=0, ‘order’=1), array(‘id’=4, ‘name’=’name4’, ‘pid’=3, ‘order’=1),
array(‘id’=5, ‘name’=’name5’, ‘pid’=6, ‘order’=1), array(‘id’=6,
‘name’=’name6’, ‘pid’=2, ‘order’=1), array(‘id’=7, ‘name’=’name7’,
‘pid’=6, ‘order’=1), array(‘id’=8, ‘name’=’name8’, ‘pid’=3, ‘order’=1),
array(‘id’=9, ‘name’=’name9’, ‘pid’=6, ‘order’=1), array(‘id’=10,
‘name’=’name10’, ‘pid’=0, ‘order’=1), array(‘id’=11, ‘name’=’name11’,
‘pid’=10, ‘order’=1), array(‘id’=12, ‘name’=’name12’, ‘pid’=10,
‘order’=1), array(‘id’=13, ‘name’=’name13’, ‘pid’=10, ‘order’=1),
array(‘id’=14, ‘name’=’name14’, ‘pid’=12, ‘order’=1), array(‘id’=15,
‘name’=’name15’, ‘pid’=12, ‘order’=4), ); echo “body
bgcolor=/”blue/””;$tree = new Catagory($data);echo
“hr下面是当前分类的类树hr”;//$tree-setExpend(1);$tree-parseNode(0);//$tree-parseNode(1);//$tree-expand(9);echo
$tree-getTreeStr();echo
“hr下面是当前分类(分类的编号是9)的路径hr”;$tree-parseCurrent(9);echo
$tree-getCurrentStr();

Php代码 

 代码如下

 
* $sourceArr 原来的数组
* $key 主键
* $parentKey 与主键关联的父主键
* $childrenKey 生成的孩子的键名
*
*/ 
 
function arrayToTree($sourceArr, $key, $parentKey, $childrenKey) 

    $tempSrcArr = array(); 
    foreach ($sourceArr as 
$v) 
    { 
        $tempSrcArr[$v[$key]] = $v; 
    } 
    $i = 0; 
    $count = count($sourceArr); 
    for($i = ($count – 1); $i >=0; $i–) 
    { 
        if (isset($tempSrcArr[$sourceArr[$i][$parentKey]])) 
        { 
           $tArr = array_pop($tempSrcArr); 
           $tempSrcArr[$tArr[$parentKey]][$childrenKey] =
(isset($tempSrcArr[$tArr[$parentKey]][$childrenKey]) &&
is_array($tempSrcArr[$tArr[$parentKey]][$childrenKey])) ?
$tempSrcArr[$tArr[$parentKey]][$childrenKey] : array(); 
           array_push
($tempSrcArr[$tArr[$parentKey]][$childrenKey], $tArr); 
        } 
    } 
    return $tempSrcArr; 

 

 
Php代码 
 
 * 将数组转换成树
 * 例子:将 array(
            array(‘id’=>1,’parentId’ => 0,’name’=> ‘name1’)
            ,array(‘id’=>2,’parentId’ => 0,’name’=> ‘name2’)
            ,array(‘id’=>4,’parentId’ => 1,’name’=>
‘name1_4’)
            ,array(‘id’=>15,’parentId’ => 1,’name’=>
‘name1_5’)
    );转换成
 * Array(
    [1] => Array([id] => 1
            [parentId] => 0
            [name] => name1
            [children] => Array(
                    [0] => Array([id] => 15,[parentId] =>
1,[name] => name1_5)
                    [1] => Array([id] => 4,[parentId] =>
1,[name] => name1_4)
                )
        )
    [2] => Array([id] => 2,[parentId] => 0,[name] =>
name2)
)
 * @param array $sourceArr 要转换的数组
 * @param string $key 数组中确认父子的key,例子中为“id”
 * @param string $parentKey 数组中父key,例子中为“parentId”
 * @param type $childrenKey
要在树节点上索引子节点的key,例子中为“children”
 * @return array 返回生成的树
 */ 

 代码如下

function arrayToTree($sourceArr, $key, $parentKey, $childrenKey) 

    $tempSrcArr = array(); 
 
    $allRoot = TRUE; 
    foreach ($sourceArr as  $v) 
    { 
        $isLeaf = TRUE; 
        foreach ($sourceArr as $cv ) 
        { 
            if (($v[$key]) != $cv[$key]) 
            { 
                if ($v[$key] == $cv[$parentKey]) 
                { 
                    $isLeaf = FALSE; 
                } 
                if ($v[$parentKey] == $cv[$key]) 
                { 
                    $allRoot = FALSE; 
                } 
            } 
        } 
        if ($isLeaf) 
        { 
            $leafArr[$v[$key]] = $v; 
        } 
        $tempSrcArr[$v[$key]] = $v; 
    } 
    if ($allRoot) 
    { 
        return $tempSrcArr; 
    } 
    else 
    { 
        unset($v, $cv, $sourceArr, $isLeaf); 
        foreach ($leafArr as  $v) 
        { 
            if (isset($tempSrcArr[$v[$parentKey]])) 
            { 
                $tempSrcArr[$v[$parentKey]][$childrenKey] =
(isset($tempSrcArr[$v[$parentKey]][$childrenKey]) &&
is_array($tempSrcArr[$v[$parentKey]][$childrenKey])) ?
$tempSrcArr[$v[$parentKey]][$childrenKey] : array(); 
                array_push
($tempSrcArr[$v[$parentKey]][$childrenKey], $v); 
                unset($tempSrcArr[$v[$key]]); 
            } 
        } 
        unset($v); 
        return arrayToTree($tempSrcArr, $key, $parentKey,
$childrenKey); 
    } 

 

 
 
Php代码 
/**递归方法:**/ 
 
$rows = array( 
    0 => array(‘id’ => 1, ‘name’ => ‘菜单1’, ‘parentId’ =>
0) 
    , 1 => array(‘id’ => 2, ‘name’ => ‘菜单2’, ‘parentId’ =>
0) 
    , 2 => array(‘id’ => 3, ‘name’ => ‘菜单3’, ‘parentId’ =>
0) 
    , 3 => array(‘id’ => 4, ‘name’ => ‘菜单1_1’, ‘parentId’
=> 1) 
    , 4 => array(‘id’ => 5, ‘name’ => ‘菜单1_2’, ‘parentId’
=> 1) 
    , 5 => array(‘id’ => 6, ‘name’ => ‘菜单2_1’, ‘parentId’
=> 2) 
); 
print_r(getTree($rows, 0, ‘id’, ‘parentId’)); 

 代码如下

 
/**
 * 数组根据父id生成树
 * @staticvar int $depth 递归深度
 * @param array $data 数组数据
 * @param integer $pid 父id的值
 * @param string $key id在$data数组中的键值
 * @param string $chrildKey 要生成的子的键值
 * @param string $pKey 父id在$data数组中的键值
 * @param int $maxDepth 最大递归深度,防止无限递归
 * @return array 重组后的数组
 */ 
function getTree($data, $pid = 0, $key = ‘id’, $pKey = ‘parentId’,
$childKey = ‘child’, $maxDepth = 0){ 
    static $depth = 0; 
    $depth++; 
    if (intval($maxDepth) <= 0) 
    { 
        $maxDepth = count($data) * count($data); 
    } 
    if ($depth > $maxDepth) 
    { 
        exit(“error recursion:max recursion depth {$maxDepth}”); 
    } 
    $tree = array(); 
    foreach ($data as $rk => $rv) 
    { 
        if ($rv[$pKey] == $pid) 
        { 
            $rv[$childKey] = getTree($data, $rv[$key], $key, $pKey,
$childKey, $maxDepth); 
            $tree[] = $rv; 
        } 
    } 
    return $tree; 

一个实例

 代码如下

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“;
<html xmlns=”;
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″
/>
<script type=”text/javascript”
src=”;
<title>TREE</title>
<style type=”text/css”>
/*树的全局CSS*/
.kyp_tree{
font: 12px/2.5 verdana;
float:left;display:inline;
}
.kyp_tree dd{
margin:0;padding:0;
margin-left:20px;
}
/*链接*/
.kyp_tree dl a{
font-size:12px;
color:#333;
text-decoration:none;
}
.kyp_tree dl a:hover, .kyp_tree dd dt.red_sub a{
font-size:12px;
color:#AE0002;
}
/*一级dl*/
.kyp_tree dl{
border-bottom:1px dashed #ccc;
margin:0;padding:0;
}
/*次级dl*/
.kyp_tree dl dl, .kyp_tree dl.last{
border:none;
}
.kyp_tree dd dt.currentClass{
background:url(tree_top.gif) no-repeat 0 -24px;
}
/*一级标题*/
.kyp_tree dt{
background:url(tree_top.gif) no-repeat 2px -57px;
padding-left:15px;
cursor:pointer;
font-size:13px;
height:30px;
line-height :27px;
line-height :32px9;
}
/*子标题*/
.kyp_tree dd dt{
background:url(tree_arrow.gif) no-repeat 2px 10px;
font-size:12px;
}
/*一级张开样式*/
.kyp_tree dt.open{
background:url(tree_top.gif) no-repeat 2px 12px;
}
/*张开样式*/
.kyp_tree dd dt.open{
background:url(tree_arrow.gif) no-repeat 0 -25px;
}
/*没有子节点的样式*/
.kyp_tree dt.nosub{
background:none;
}
</style>
<script type=”text/javascript”>
//<![CDATA[
jQuery.fn.createTree = function (fn, ini){
var $ = jQuery, ini = Object(ini);
this.find(‘dd’).hide();
this.children(‘dl:last’).addClass(‘last’);
this.find(‘dt’, this).each(function (){
var nosub = $(this).next(‘dd’).size() == 0;
if (nosub) {
$(this).addClass(‘nosub’);
}
if (ini.id && ini.id == $(this).attr(‘classify’)) {
$(this).parents(‘dd’).show().prev(‘dt’).addClass(‘open’);
$(this).addClass(‘red_sub’);
if (nosub) {
$(this).addClass(‘currentClass’)
}else{
$(this).next(‘dd’).show();
$(this).addClass(‘open’)
}
}
}).click(function (e){
var dd = $(this).next(‘dd’),
isClose = dd.css(‘display’) == ‘none’;
if (dd.size()) {
if (isClose) {
dd.show();
$(this).addClass(‘open’)
}else{
dd.hide();
$(this).removeClass(‘open’)
}
}
return fn && fn.call(this, e, dd)
});
if (ini.mx) {
this.find(‘dt’).click(function (e){
var J = $(this);
if (J.next(‘dd’).size()) {
if (J.hasClass(‘open’)) {
J.parent().siblings(‘dl’).children(‘dd’).hide();
J.parent().siblings(‘dl’).children(‘dt’).removeClass(‘open’);
J.next(‘dd’).show();
J.addClass(‘open’)
}
}
})
}
};
(function ($){
$(function (){
$(‘#tree_wrap’).createTree(function (e, dd){//回调(事件, 下一个dd)
$(‘#show’).html(this.innerHTML+dd.size())
}, {mx: 1, id: 200})// mx是否互斥, id 当前类别
});
})(jQuery)
//]]>
</script>
</head>
<body>

<?php

// 树组的顺序即是分类的顺序,因此前当分类的下级子类一定要紧随其后
$tree= array(
1 => array(‘id’=>1, ‘cname’=>’一级分类’, ‘pid’=>0),

100 => array(‘id’=>100, ‘cname’=>’特意加进去的二级分类’,
‘pid’=>1),
101 => array(‘id’=>101,
‘cname’=>’特意加进去的二级分类2222222222’, ‘pid’=>1),

2 => array(‘id’=>2, ‘cname’=>’二级分类’, ‘pid’=>1),
3 => array(‘id’=>3, ‘cname’=>’三级分类’, ‘pid’=>2),
4 => array(‘id’=>4, ‘cname’=>’四级分类’, ‘pid’=>3),
5 => array(‘id’=>5, ‘cname’=>’四级分类2’, ‘pid’=>3),
200 => array(‘id’=>200, ‘cname’=>’55555’, ‘pid’=>5),
6 => array(‘id’=>6, ‘cname’=>’另一级分类’, ‘pid’=>0),
7 => array(‘id’=>7, ‘cname’=>’First First First’,
‘pid’=>0),
8 => array(‘id’=>8, ‘cname’=>’First First First’,
‘pid’=>7),
);

// 指定分类ID,返回子类量(不进行深度递归)
function getChildTotal($id)
{
global $tree;
$total = 0;
foreach($tree as $value)
{
if ($id == $value[‘pid’])
{
$total++;
}
}
return $total;
}

 

//
指定分类ID,www.111cn.net并返回数组(不进行深度递归)
function getChildArray($id)
{
global $tree;
$array = array();
foreach($tree as $key=>$value)
{
if ($id == $value[‘pid’])
{
$array[$key] = $value;
}
}
return $array;
}

// 递归查询方式将树数组转换成HTML嵌套树

function getTreeHTML($tree,$level = 0)
{
if ($tree)
{
$level += 1;
foreach($tree as $id => $node)
{
$html .= “<dl>”;
$html .= ‘<dt classify=”‘.$node[‘id’].'”><a
href=”;”;
if (getChildTotal($node[‘id’]))
{
$tree_last = getChildArray($node[‘id’]);

$html .= ‘<dd>’;
$html .= getTreeHTML($tree_last,$level);
$html .= ‘</dd>’;

}
$html .= ‘</dl>’;
}
}
return $html;
}

$html = getTreeHTML( getChildArray(0) );
echo ‘<div id=”tree_wrap” class=”kyp_tree”>’;
echo $html;
echo ‘</div><div id=”show” style=”clear:both;border-top:1px
solid red”></div>’;

?>
</body>
</html>

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图