php+mysql生成父子樹結構


項目中可以經常要生成tree結構, 一般都是從數據庫里讀父子表,

方式很多種,哪種最好呢?  下面舉個示例:

數據庫:

 1 --
 2 -- 表的結構 `oa_group`
 3 --
 4 
 5 CREATE TABLE IF NOT EXISTS `oa_group` (
 6   `id` int(11) NOT NULL AUTO_INCREMENT,
 7   `describe` varchar(50) NOT NULL,
 8   `auth` varchar(20) DEFAULT NULL,
 9   `parent_id` int(11) NOT NULL DEFAULT '0',
10   PRIMARY KEY (`id`)
11 ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=44 ;
12 
13 --
14 -- 轉存表中的數據 `oa_group`
15 --
16 
17 INSERT INTO `oa_group` (`id`, `describe`, `auth`, `parent_id`) VALUES
18 (1, ' 管理員', '["all"]', 0),
19 (2, '業務經理', '["1","3"]', 0),
20 (3, '片區主管', '', 0),
21 (4, '業務員', '', 3),
22 (5, '數據查看', '', 1),
23 (6, '錄入員', '', 5),
24 (7, '碩放片區', '', 2),
25 (8, '梅村片區', '', 3),
26 (12, '王經理', '', 8),
27 (13, '老王經理', '', 2),
28 (42, '新增組', '', 0),
29 (43, '新增0組', '', 42);

方法一:(遞歸)

<?php 

function getSql($sql){
    $link = mysql_connect('127.0.0.1','root','wc');
    if (!$link) { 
        die('Could not connect to MySQL: ' . mysql_error()); 
    } 
    mysql_select_db("test",$link);
    mysql_query("SET NAMES utf8"); 

    $result = mysql_query($sql);
    $data = array();
    while($row=mysql_fetch_array($result,1)){
        $data[] = $row;
    }
    mysql_close($link); 
    return $data;
}

function toJson($pid=0){
    $sql="select id,`describe` as text from oa_group where parent_id={$pid}";
    $data = getSql($sql);
    $jsonData = array();
    foreach($data as $v){
        $jsonData[$v['id']] = $v;
        $child = toJson($v['id']);
        if(!empty($child))
            $jsonData[$v['id']]['children'] = array_values($child);
    }
    return $jsonData;
}

print_r((toJson()));
//print_r(json_encode(array_values(toJson())));
?> 

這種方法就是簡單,一看就懂, 但是效率很低,這樣循環的讀數據庫TCP開銷太大.

方法二:(循環)

 1 function toJson2(){
 2   $json_data = array();
 3   $sql="select * from oa_group";
 4     $data = getSql($sql);
 5 
 6   foreach($data as $value){
 7       $json_data[$value['id']] = array('id' => $value['id'], 'text' => $value['describe'], 'parent_id' => $value['parent_id']);
 8   }
 9   foreach($json_data as $v){
10       unset($json_data[$v['id']]['parent_id']);
11       if($v['parent_id'] != 0){
12           $json_data[$v['parent_id']]['children'][] = $json_data[$v['id']];
13           unset($json_data[$v['id']]);
14       }
15   }
16   ksort($json_data);
17   return $json_data;
18 }

這種方法看起來挺好, 可以要兩次循環,能不能優化下呢?

方法三:

 1 function toJson3(){
 2   $json_data = array();
 3   $sql="select * from oa_group order by id desc";
 4     $data = getSql($sql);
 5     //print_r($data);
 6   foreach($data as $v){
 7   //    $json_data[$value['id']] = array('id' => $value['id'], 'text' => $value['describe'], 'parent_id' => $value['parent_id']);
 8   //}
 9   //foreach($json_data as $v){
10       //unset($json_data[$v['id']]['parent_id']);
11       $json_data[$v['id']] = isset($json_data[$v['id']]) ? $v + $json_data[$v['id']] : $v;
12       if($v['parent_id'] != 0){
13           $json_data[$v['parent_id']]['children'][] = $json_data[$v['id']];
14           unset($json_data[$v['id']]);
15       }
16       //$json_data[$v['id']] = $v;
17   }
18   ksort($json_data);
19   return $json_data;
20 }

和方法二比,這優化了很多. 但要注意的兩者之間的區別:

方法二中的sql語句和方法二比少了一個order by id desc.且parent_id不於id

這很重要,因為方法三中$json_data[$v['parent_id']]['children'][]時如果沒有排序id..那么可能這個數據的index還沒有生成.

由此可以看出,方法三的局限性在於: parent_id必須比id小.當然一般id自動編號的話這是肯定比它小的,

手工指定的parent_id還是方法二比較有效!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM