데이터베이스 결과로부터 다차원 배열을 생성하는 재귀 함수
PHP데이터베이스 결과로부터 다차원 배열을 생성하는 재귀 함수
나는 (플랫 데이터베이스 결과에서) 페이지 / 카테고리의 배열을 취하고 부모 ID를 기반으로하는 중첩 페이지 / 카테고리 항목의 배열을 생성하는 함수를 작성하려고합니다. 이 반복적 인 작업을 수행하여 모든 중첩 수준을 수행 할 수 있습니다.
예 : 하나의 쿼리에서 모든 페이지를 가져 오는 중이며 이것이 데이터베이스 테이블의 모습입니다.
+-------+---------------+---------------------------+
| id | parent_id | title |
+-------+---------------+---------------------------+
| 1 | 0 | Parent Page |
| 2 | 1 | Sub Page |
| 3 | 2 | Sub Sub Page |
| 4 | 0 | Another Parent Page |
+-------+---------------+---------------------------+
그리고 이것은 내 뷰 파일을 처리하기 위해 끝내기를 원하는 배열입니다.
Array
(
[0] => Array
(
[id] => 1
[parent_id] => 0
[title] => Parent Page
[children] => Array
(
[0] => Array
(
[id] => 2
[parent_id] => 1
[title] => Sub Page
[children] => Array
(
[0] => Array
(
[id] => 3
[parent_id] => 1
[title] => Sub Sub Page
)
)
)
)
)
[1] => Array
(
[id] => 4
[parent_id] => 0
[title] => Another Parent Page
)
)
내가 보아 왔던 거의 모든 솔루션을 보았고 거의 모든 솔루션을 시도했다. 스택 오버플로에는 여기에 많은 것들이 있지만 페이지와 카테고리 모두에서 작동 할만큼 충분히 일반적인 것을 얻지는 않았다.
여기에 내가 가장 가까이있는 부분이 있지만 첫 번째 수준의 부모에게 자식을 할당하기 때문에 작동하지 않습니다.
function page_walk($array, $parent_id = FALSE)
{
$organized_pages = array();
$children = array();
foreach($array as $index => $page)
{
if ( $page['parent_id'] == 0) // No, just spit it out and you're done
{
$organized_pages[$index] = $page;
}
else // If it does,
{
$organized_pages[$parent_id]['children'][$page['id']] = $this->page_walk($page, $parent_id);
}
}
return $organized_pages;
}
function page_list($array)
{
$fakepages = array();
$fakepages[0] = array('id' => 1, 'parent_id' => 0, 'title' => 'Parent Page');
$fakepages[1] = array('id' => 2, 'parent_id' => 1, 'title' => 'Sub Page');
$fakepages[2] = array('id' => 3, 'parent_id' => 2, 'title' => 'Sub Sub Page');
$fakepages[3] = array('id' => 4, 'parent_id' => 3, 'title' => 'Another Parent Page');
$pages = $this->page_walk($fakepages, 0);
print_r($pages);
}
해결법
-
==============================
1.아주 단순하고 일반적인 트리 구조 :
아주 단순하고 일반적인 트리 구조 :
function buildTree(array $elements, $parentId = 0) { $branch = array(); foreach ($elements as $element) { if ($element['parent_id'] == $parentId) { $children = buildTree($elements, $element['id']); if ($children) { $element['children'] = $children; } $branch[] = $element; } } return $branch; } $tree = buildTree($rows);
알고리즘은 매우 간단합니다.
즉,이 함수를 한 번 실행하면 주어진 부모 ID의 자식 인 요소 목록이 반환됩니다. buildTree ($ myArray, 1)로 호출하면, 부모 ID가 1 인 요소의 목록을 반환합니다. 처음에는 부모 ID가 0 인이 함수를 호출하므로 루트 ID 인 부모 ID가없는 요소가 반환됩니다. 이 함수는 자식을 찾기 위해 재귀 적으로 호출합니다.
-
==============================
2.나는이 질문이 오래되었다는 것을 알고 있지만, 매우 많은 양의 데이터를 제외하고는 매우 비슷한 문제에 직면했다. 몇 가지 어려움을 겪은 후, 나는 참조를 사용하여 결과 집합의 한 번에 트리를 만들 수 있었다. 이 코드는 꽤 좋지는 않지만 작동하며 매우 빠르게 작동합니다. 그것은 비 재귀 적입니다 - 즉, 결과 집합을 한 번 통과 한 다음 끝에 하나의 array_filter가 있습니다.
나는이 질문이 오래되었다는 것을 알고 있지만, 매우 많은 양의 데이터를 제외하고는 매우 비슷한 문제에 직면했다. 몇 가지 어려움을 겪은 후, 나는 참조를 사용하여 결과 집합의 한 번에 트리를 만들 수 있었다. 이 코드는 꽤 좋지는 않지만 작동하며 매우 빠르게 작동합니다. 그것은 비 재귀 적입니다 - 즉, 결과 집합을 한 번 통과 한 다음 끝에 하나의 array_filter가 있습니다.
$dbh = new PDO(CONNECT_STRING, USERNAME, PASSWORD); $dbs = $dbh->query("SELECT n_id, n_parent_id from test_table order by n_parent_id, n_id"); $elems = array(); while(($row = $dbs->fetch(PDO::FETCH_ASSOC)) !== FALSE) { $row['children'] = array(); $vn = "row" . $row['n_id']; ${$vn} = $row; if(!is_null($row['n_parent_id'])) { $vp = "parent" . $row['n_parent_id']; if(isset($data[$row['n_parent_id']])) { ${$vp} = $data[$row['n_parent_id']]; } else { ${$vp} = array('n_id' => $row['n_parent_id'], 'n_parent_id' => null, 'children' => array()); $data[$row['n_parent_id']] = &${$vp}; } ${$vp}['children'][] = &${$vn}; $data[$row['n_parent_id']] = ${$vp}; } $data[$row['n_id']] = &${$vn}; } $dbs->closeCursor(); $result = array_filter($data, function($elem) { return is_null($elem['n_parent_id']); }); print_r($result);
이 데이터에서 실행될 때 :
mysql> select * from test_table; +------+-------------+ | n_id | n_parent_id | +------+-------------+ | 1 | NULL | | 2 | NULL | | 3 | 1 | | 4 | 1 | | 5 | 2 | | 6 | 2 | | 7 | 5 | | 8 | 5 | +------+-------------+
마지막 print_r은 다음과 같은 출력을 생성합니다 :
Array ( [1] => Array ( [n_id] => 1 [n_parent_id] => [children] => Array ( [3] => Array ( [n_id] => 3 [n_parent_id] => 1 [children] => Array ( ) ) [4] => Array ( [n_id] => 4 [n_parent_id] => 1 [children] => Array ( ) ) ) ) [2] => Array ( [n_id] => 2 [n_parent_id] => [children] => Array ( [5] => Array ( [n_id] => 5 [n_parent_id] => 2 [children] => Array ( [7] => Array ( [n_id] => 7 [n_parent_id] => 5 [children] => Array ( ) ) [8] => Array ( [n_id] => 8 [n_parent_id] => 5 [children] => Array ( ) ) ) ) [6] => Array ( [n_id] => 6 [n_parent_id] => 2 [children] => Array ( ) ) ) ) )
정확히 내가 찾던 것이 맞습니다.
-
==============================
3.PHP를 사용하여 mysql 결과를 배열로 가져온 다음이를 사용할 수 있습니다.
PHP를 사용하여 mysql 결과를 배열로 가져온 다음이를 사용할 수 있습니다.
$categoryArr = Array(); while($categoryRow = mysql_fetch_array($category_query_result)){ $categoryArr[] = array('parentid'=>$categoryRow['parent_id'], 'id'=>$categoryRow['id']); }
from https://stackoverflow.com/questions/8587341/recursive-function-to-generate-multidimensional-array-from-database-result by cc-by-sa and MIT license
'PHP' 카테고리의 다른 글
setcookie () 후 즉시 $ _COOKIE에 액세스 (0) | 2018.09.09 |
---|---|
PHP를 사용하여 SQL Server에서 문자열을 이스케이프 처리하는 방법은 무엇입니까? (0) | 2018.09.09 |
PHP에서 브라우저 언어 감지 (0) | 2018.09.09 |
모바일 장치를 감지하는 가장 간단한 방법 (0) | 2018.09.09 |
PHP 배열을 저장하는 기본 방법 (json_encode 대 serialize) (0) | 2018.09.09 |