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 返回生成的树
PHP代码如下:
- 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,并返回数组(不进行深度递归)
- 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 class="kyp_tree">';
- echo $html;
- echo '</div><div ></div>';
- ?>
- </body>
- </html>