php数组转换成树的几个例子

php数组转换成树的几个例子

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" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

<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="http://www.baidu.com/">'.$node['cname']."</a></dt>";

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

echo $html;

echo '</div><div ></div>';

?>

</body>

</html>