2016-09-21 3 views
3

추천 시스템에서 일하고 있습니다. 사용자 A는 사용자 B와 사용자 C를 초대하고 사용자 B는 사용자 D를 초대하고 사용자 C는 사용자 E를 초대합니다. 어떻게 모든 자식과 손자 노드를 반복 할 수 있습니까? 여기 주어진 부모 ID의 모든 자식 노드와 손자 노드 찾기 PHP

내 DB의 예 데이터 인

ID  name  referral_id 
1  user A  null//assume the tree starts from here 
2  user B  1 
3  user C  1 
4  user D  2 
5  user E  3 

I 부모로서, 유저 (A)를 검색하고 (그리고 사용자 C (하위 노드 D로) 사용자 B를 나열하는 기능을 만드는 방법 하위 노드 E)?

내가 CI를 사용하고,이 알고리즘의 몇 가지 유형을했을

$downline_query = $this->db->query("SELECT * FROM user WHERE referral_id = '1'") 
//above query will return user B and C as result.. hardcoded for example 

$downline = array(); 
foreach($downline_query as $result){ 
    $downline[] = array( 
     "name" => $result['name'], 
     "id" => $result['id'] 
    ); 
} 
//above $downline array will only contain user B and C. I don't know where to go again after this step.. 

$records = array("data"=>$downline); 
echo json_encode($records); 

나는 곳이 단계 .. 후 가야 모르는 부모 ID에서이 하위 노드를 검색하는 내 쿼리입니다 while 루프 및 foreach 루프가 포함됩니다. 그러나 그것은 여전히 ​​"역동적 인"것이 아닙니다.

나는 모든 아이들과 손주들의 이름과 ID가 필요하다는 것을 알려드립니다. 다차원 배열 일 필요는 없습니다. 내가 모든 아이들을 얻을 수있는 한, granchildren과 great-grand-children은 이미 괜찮습니다 ..

$ 하위 라인 배열에 모든 자식과 손자 등을 저장할 계획입니다. 그래서 모두가 ...

정말이 작업을 수행하는 방법에 대한 지침을 필요로 다차원 배열없이 1 개 배열되기 전에이 계층 구조 꼬추를 해본 적이 .. 당신에게 :) 감사합니다 $downline_query 가정

+2

를 얻을 .. http://mikehillyer.com/articles/managing-hierarchica에서 살펴보십시오. l-data-in-mysql/..이 링크는 매우 유용합니다. –

+0

이 링크 질문을 참조하십시오. [만들기 트리] (http://stackoverflow.com/questions/34433056/unable-to-retrieve-the-sub-categories/34433727#34433727) – kc1994

+1

단일 루프 실 거예요이 일을 위해, 당신은 모든 데이터를 구성하려고 시도하기 전에 데이터를 가져와야합니다. 그렇지 않으면 순서가 잘못되어 있으면 놓칠 수 있습니다. 첫 번째 루프에서 ID로 순서대로 정렬해야합니다 (두 번째 루프에서는 ID/KEY의 첫 번째 배열에서 관련 데이터를 가져 와서 두 번째 배열을 만듭니다) – ArtisticPhoenix

답변

0

이 무엇을해야이 포함 된 모든 필요한 행. IE 1 DB 쿼리.

$affilites = []; 
$parents = [] 
foreach($downline_query as $row){ 
    if($row['referral_id']){ 
     if(!isset( $affilites[$row['referral_id']])){ 
      $affilites[$row['referral_id']] = []; 
     } 
     $affilites[$row['referral_id']][] = $row; 
    }else{ 
     $parents[$row['id']] = $row; 
    } 
} 
// you now have 2 arrays 1 of parents, one of children. now just combine (shown below) 
$parent = [ 
    1 => ['ID'=>1,'name'=>'user A', 'referral_id' =>null], 
]; 

$affiliate = [ 
    1 => [ 
      ['ID'=>2,'name'=>'user B', 'referral_id' =>1], 
      ['ID'=>3,'name'=>'user C', 'referral_id' =>1], 
     ], 
    2 => [['ID'=>4,'name'=>'user D', 'referral_id' =>2]], 
    3 => [['ID'=>5,'name'=>'user E', 'referral_id' =>3]], 
    5 => [['ID'=>16,'name'=>'user F', 'referral_id' =>5]], 
]; 


print_r(getparents($parent, $affiliate)); 

function getparents($parent, $affiliate){ 
    $result = []; 
    foreach ($parent as $row){ 
     $id = $row['ID']; 

     $result[] = $row; 

     if(isset($affiliate[$id])){ 
     //no children 
      $result[$id]['children'] = getparents($affiliate[$id], $affiliate); //recurse 
     } 
    } 
    return $result; 
} 

그리고 최종 출력

Array(
     [0] => Array(
       [ID] => 1 
       [name] => user A 
       [referral_id] => 
       [children] => Array(
         [0] => Array(
           [ID] => 2 
           [name] => user B 
           [referral_id] => 1 
           [children] => Array(
             [0] => Array(
               [ID] => 4 
               [name] => user D 
               [referral_id] => 2 
               ) 

             ) 

           ) 

         [1] => Array(
           [ID] => 3 
           [name] => user C 
           [referral_id] => 1 
           [children] => Array(
             [0] => Array(
               [ID] => 5 
               [name] => user E 
               [referral_id] => 3 
               [children] => Array(
                 [0] => Array(
                   [ID] => 16 
                   [name] => user F 
                   [referral_id] => 5 
                   ) 

                 ) 

               ) 

             ) 

           ) 

         ) 

       ) 

     ) 
+0

선생님이 보관합니다 자식 노드에서 모든 노드 노드로 반복 수행할까요? – Vinfoster0701

+0

아니요 하나만 깊게 작동합니다. 그렇게하려면 재귀 적으로 만들어야합니다. 하지만이 경우 나 중첩 된 경로를 사용하는 것이 좋습니다. 왜냐하면 부모 자식 관계 대신에 계층 구조가 있기 때문입니다. – ArtisticPhoenix

+0

구체화 된 경로가 좋은 선택입니다. – ArtisticPhoenix

-1

당신은 재귀 함수 시도 할 수 있습니다 :

function get_referrals ($referral_id){ 
    $downline = array(); 
    $downline_query = $this->db->query("SELECT * FROM user WHERE referral_id = '$referral_id'"); 
    foreach($downline_query as $result){ 
     $downline[] = array(
      "name" => $result['name'], 
      "id" => $result['id'] 
     ); 
     $downline['invited'] = get_referrals($result['id']); # <--- recursive !!! 
    } 
    return $downline; 
} 

을하고 이런 종류의 구조 검색어에 대한 $의 다운

$downline = get_referrals(1); 


print_r($downline); 
+0

대답은 SQL 주입에 취약하므로 준비된 문을 사용하는 것이 좋습니다 (예 :'get_referrals ("DROP TABLE users; -"); ' – ArtisticPhoenix

+0

). 유일한 해결책은 ... 최종 코드가 아닙니다. 구현은 Vinfoster0701 개발자가 수행해야합니다.원하는 결과가 생성됩니다. – Federico

관련 문제