問題:設計公司的員工表,員工有不同級別,要求可通過一個員工查到其下屬的所有員工,也可查到其所屬的上級。
解決:遞歸實現無限分類思想,每一個員工存入其所屬的上級的id作為自己的pid,另外存入path,path包含自身id,方便顯示路徑。
遞歸的注意點:
1.一定有一個判斷條件,否則遞歸就死循環了
2.每次的遞歸結果要保存起來,變量自增的實現三種方式:
function(&$bar):通過引用地址
global :通過設置為全局變量
static :設置為靜態變量
header( "Content-type: text/html; charset=utf-8" ); $arr = array( array( 'uid'=>'1', 'name'=>'總監張', 'pid'=>'0', 'path'=>'0,' ),
array( 'uid'=>'2', 'name'=>'副總王', 'pid'=>'1', 'path'=>'0,1,' ),
array( 'uid'=>'3', 'name'=>'經理趙', 'pid'=>'2', 'path'=>'0,1,2,' ),
array( 'uid'=>'4', 'name'=>'員工趙', 'pid'=>'6', 'path'=>'0,1,2,3,6,' ),
array( 'uid'=>'5', 'name'=>'員工房', 'pid'=>'6', 'path'=>'0,1,2,3,6,' ),
array( 'uid'=>'6', 'name'=>'組長劉', 'pid'=>'3', 'path'=>'0,1,2,3,' ),
array( 'uid'=>'7', 'name'=>'經理光桿', 'pid'=>'2', 'path'=>'0,1,2,' ), ); /** * 通過傳入要查找的人的pid來遞歸查找他的下屬,代碼簡陋,理解精神為主 * @param array $data 數組代替數據庫中的數據 * @param integer $pid 父id * @param array &$result 結果數組,&保證變量常駐 * @param integer $deep 輸出的分隔符--,無實際意義 * @return 樹狀結構數組 */
function getList( $data, $pid=0, &$result=array(), $deep = 0 ) { $deep+=2; foreach ( $data as $key => $val ) { if ( $pid == $val['pid'] ) { $result[] = "|".str_repeat("--", $deep).$val['name']; getList( $data, $val['uid'], $result, $deep ); } } return $result; } //調用函數輸出結果
$res = getList($arr, 1); //查找副總王的下屬 foreach($res as $key=>$val){ echo $val."\n"; }
/*
|----副總王
|--------經理趙
|------------組長劉
|----------------員工趙
|----------------員工房
|--------經理光桿
*/
還是上邊的數據,現在要查一個員工的所有上級
/** * 傳入員工的id,可以查找員工所屬的上級 * @param array $data 數組代替數據庫中的數據 * @param integer $id 要查找的員工的id * @param array &$result 結果數組,&保證變量常駐 * @return 結果 */
function getLink($data, $id=0, &$result=array()){ foreach ($data as $key => $val) { if ($val['uid'] == $id) { $result[] = $val['name']; getLink($data, $val['pid'], $result); } } return $result; } $res = getLink($arr , 5); //查找員工房的上級
foreach ($res as $key => $val) { echo $val." | "; } /* 員工房 | 組長劉 | 經理趙 | 副總王 | 總監張 | */
注:也可用全路徑無限分類:數據中存了path,全路徑可通過concat(path,",",id)算出來。
優點:查詢快,比遞歸快
缺點:增加,移動分類時稍顯復雜
