IT

관계의 부모-자식 관계를 계층 적 트리로 변환 하시겠습니까?

lottoking 2020. 8. 26. 08:09
반응형

관계의 부모-자식 관계를 계층 적 트리로 변환 하시겠습니까?


가능한 한 약간의 약간의 계층 구조 트리 구조로 바꾸고 싶은 이름-부모 이름 쌍이 많이 있습니다. 예를 들어 다음과 같은 쌍이 될 수 있습니다.

Child : Parent
    H : G
    F : G
    G : D
    E : D
    A : E
    B : C
    C : E
    D : NULL

(a) 계층 적 트리로 변환해야합니다.

D
├── E
│   ├── A
│   │   └── B
│   └── C   
└── G
    ├── F
    └── H

내가 원하는 최종 결과는 <ul>추가 <li>의 이름을 포함 하는 중첩 된 요소 집합입니다 .

쌍에는 불일치가 내부 (하위는 자신의 부모, 부모는 마이너스 등) 많은 최적화를 수행 할 수 있습니다.

PHP에서 어떻게 child => parent 쌍을 포함하는 배열에서 중첩 세트로 몇 개의 <ul>서열을 가지고 있습니까?

재귀가 관련되어 있다고 생각합니다.


어느 쪽이든 / 부모 쌍을 트리 구조로 구문 분석하는 매우 기본적인 재귀 함수와이를 인쇄하기 또위한 재귀 함수가 있습니다. 하나의 기능만으로 충분하지만 명확성을 위해 두 가지 기능이 있습니다.

먼저 먼저 / 부모 쌍의 배열을 초기화합니다.

$tree = array(
    'H' => 'G',
    'F' => 'G',
    'G' => 'D',
    'E' => 'D',
    'A' => 'E',
    'B' => 'C',
    'C' => 'E',
    'D' => null
);

그런 다음 해당 배열을 계층 트리 구조로 구문 분석하는 함수 :

function parseTree($tree, $root = null) {
    $return = array();
    # Traverse the tree and search for direct children of the root
    foreach($tree as $child => $parent) {
        # A direct child is found
        if($parent == $root) {
            # Remove item from tree (we don't need to traverse this again)
            unset($tree[$child]);
            # Append the child into result array and parse its children
            $return[] = array(
                'name' => $child,
                'children' => parseTree($tree, $child)
            );
        }
    }
    return empty($return) ? null : $return;    
}

그리고 그 트리를 순회하여 정렬되지 않은 목록을 출력하는 함수 :

function printTree($tree) {
    if(!is_null($tree) && count($tree) > 0) {
        echo '<ul>';
        foreach($tree as $node) {
            echo '<li>'.$node['name'];
            printTree($node['children']);
            echo '</li>';
        }
        echo '</ul>';
    }
}

그리고 실제 사용 :

$result = parseTree($tree);
printTree($result);

의 내용은 다음과 가변 $result됩니다.

Array(
    [0] => Array(
        [name] => D
        [children] => Array(
            [0] => Array(
                [name] => G
                [children] => Array(
                    [0] => Array(
                        [name] => H
                        [children] => NULL
                    )
                    [1] => Array(
                        [name] => F
                        [children] => NULL
                    )
                )
            )
            [1] => Array(
                [name] => E
                [children] => Array(
                    [0] => Array(
                        [name] => A
                        [children] => NULL
                    )
                    [1] => Array(
                        [name] => C
                        [children] => Array(
                            [0] => Array(
                                [name] => B
                                [children] => NULL
                            )
                        )
                    )
                )
            )
        )
    )
)

좀 더 효율성을 원하면 함수를 하나로 결합하여 반복 횟수를 수 있습니다.

function parseAndPrintTree($root, $tree) {
    $return = array();
    if(!is_null($tree) && count($tree) > 0) {
        echo '<ul>';
        foreach($tree as $child => $parent) {
            if($parent == $root) {                    
                unset($tree[$child]);
                echo '<li>'.$child;
                parseAndPrintTree($child, $tree);
                echo '</li>';
            }
        }
        echo '</ul>';
    }
}

이만큼 작은 데이터 세트에 8 번의 반복 만 저장하지만 더 큰 세트에서는 차이를 만들 수 있습니다.


트리를 만드는 또 다른 함수 (재귀가 필요하지 않고 대신 참조를 사용함) :

$array = array('H' => 'G', 'F' => 'G', ..., 'D' => null);

function to_tree($array)
{
    $flat = array();
    $tree = array();

    foreach ($array as $child => $parent) {
        if (!isset($flat[$child])) {
            $flat[$child] = array();
        }
        if (!empty($parent)) {
            $flat[$parent][$child] =& $flat[$child];
        } else {
            $tree[$child] =& $flat[$child];
        }
    }

    return $tree;
}

다음과 같은 계층 적 배열을 반환합니다.

Array(
    [D] => Array(
        [G] => Array(
            [H] => Array()
            [F] => Array()
        )
        ...
    )
)

재귀 함수를 사용하여 HTML 목록으로 쉽게 인쇄 할 수 있습니다.


의 플랫 구조를 $tree계층 구조로 변환하는 더 간단한 또 ​​다른 방법 입니다. 노출 비용 임시 배열이 하나만 필요합니다.

// add children to parents
$flat = array(); # temporary array
foreach ($tree as $name => $parent)
{
    $flat[$name]['name'] = $name; # self
    if (NULL === $parent)
    {
        # no parent, is root element, assign it to $tree
        $tree = &$flat[$name]; 
    }
    else
    {
        # has parent, add self as child    
        $flat[$parent]['children'][] = &$flat[$name];
    }
}
unset($flat);

이것이 계층 구조를 다차원 배열로 가져 오는 것입니다.

Array
(
    [children] => Array
        (
            [0] => Array
                (
                    [children] => Array
                        (
                            [0] => Array
                                (
                                    [name] => H
                                )

                            [1] => Array
                                (
                                    [name] => F
                                )

                        )

                    [name] => G
                )

            [1] => Array
                (
                    [name] => E
                    [children] => Array
                        (
                            [0] => Array
                                (
                                    [name] => A
                                )

                            [1] => Array
                                (
                                    [children] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [name] => B
                                                )

                                        )

                                    [name] => C
                                )

                        )

                )

        )

    [name] => D
)

재귀를 피하려는 경우 덜 간단합니다 (큰 구조의 경우 부담이 될 수 있음).

저는 어레이 출력에 대한 UL / LI "딜레마"를 항상 해결하고 싶었습니다. 딜레마는 각 항목이 마이너스가 조치를하거나 또는 종료 아야하는 선행 요소의 수를 알지 수단은 것입니다. 또 다른 대답에서 나는 이미 a를 사용하고 내가 다른 메타 정보를 RecursiveIteratorIterator찾아서 해결했습니다 . 중첩 된 세트 모델을 "닫힌"하위 트리 로 가져 오기 . 대답 은 반복적으로 사용하면 매우 유연하다는 것을 보여줍니다.getDepth()Iterator<ul>

귀하의 승인을받지 않을 것입니다. 또한 나는 항상 표준 트리 구조와 HTML <ul><li>요소에 대해 해결하고 싶었습니다 .

내가 생각 해낸 기본 개념은 다음과 가변합니다.

  1. TreeNode-각 요소를 TreeNode값 (예 :) Name과 마이너스가 있는지 여부를 제공 할 수 있는 간단한 유형으로 추상화합니다 .
  2. TreeNodesIterator- RecursiveIterator이 세트 (배열)를 반복 할 수 있습니다 TreeNodes. TreeNode어떤 종류가 이미 존재하는지, 어떤 것이 있는지 알고 있기 때문에 매우 간단 합니다.
  3. RecursiveListIterator-다음 RecursiveIteratorIterator과 같은 유형을 반복적으로 반복 할 때 필요한 모든 이벤트가 있는 A 입니다 RecursiveIterator.
    • beginIteration/ endIteration-기본 목록의 시작과 끝.
    • beginElement/ endElement-각 요소의 시작과 끝.
    • beginChildren/ endChildren-각 어린이 목록의 시작과 끝. RecursiveListIterator함수 호출의 형태로만 이러한 이벤트를 제공합니다. 목록에서 일반적으로 사용되는 마이너스 목록은 <ul><li>부모 <li>요소 내에서 열리고 닫힘 . 따라서 endElement이벤트는 해당 이벤트가 시작 endChildren됩니다. 이 클래스의 사용을 확대하기 위해 변경하거나 구성 할 수 있습니다. 이벤트는 데코레이터 객체에 대한 함수 호출로 배포되어 사물을 분리합니다.
  4. ListDecorator-의 이벤트를 수신하는 "장식 자"클래스입니다 RecursiveListIterator.

메인 출력부터 시작합니다. 이제 계층 적 $tree배열을 취하면 최종 코드는 다음과 달라집니다.

$root = new TreeNode($tree);
$it = new TreeNodesIterator(array($root));
$rit = new RecursiveListIterator($it);
$decor = new ListDecorator($rit);
$rit->addDecorator($decor);

foreach($rit as $item)
{
    $inset = $decor->inset(1);
    printf("%s%s\n", $inset, $item->getName());
}

먼저 요소 ListDecorator를 단순히 래핑 하고 목록 구조가 출력되는 방식을 결정 하는를 살펴 보겠습니다.<ul><li>

class ListDecorator
{
    private $iterator;
    public function __construct(RecursiveListIterator $iterator)
    {
        $this->iterator = $iterator;
    }
    public function inset($add = 0)
    {
        return str_repeat('  ', $this->iterator->getDepth()*2+$add);
    }

생성자는 작업중 인 목록을 사용합니다. inset출력의 좋은 들여 쓰기를위한 도우미 함수입니다. 나머지는 각 이벤트에 대한 출력 함수입니다.

    public function beginElement()
    {
        printf("%s<li>\n", $this->inset());
    }
    public function endElement()
    {
        printf("%s</li>\n", $this->inset());
    }
    public function beginChildren()
    {
        printf("%s<ul>\n", $this->inset(-1));
    }
    public function endChildren()
    {
        printf("%s</ul>\n", $this->inset(-1));
    }
    public function beginIteration()
    {
        printf("%s<ul>\n", $this->inset());
    }
    public function endIteration()
    {
        printf("%s</ul>\n", $this->inset());
    }
}

여기서는 다음과 같이 주요 출력 마무리 / 루프 단계별로 진행합니다.

$root = new TreeNode($tree);

TreeNode반복을 시작하는 데 사용할 루트 만듭니다 .

$it = new TreeNodesIterator(array($root));

이것은 단일 노드 에 대한 재귀 적 반복을 가능하게 TreeNodesIterator하는 것 RecursiveIterator입니다 $root. 이 클래스는 반복 할 수 있기 때문에 필요하고 TreeNode요소 의 배열이기도 한 하위 집합과 함께 할 수 있기 때문에 배열로 전달 됩니다.

$rit = new RecursiveListIterator($it);

이것은 RecursiveListIteratorRecursiveIteratorIterator상기 이벤트를 제공한다. 그것을 사용하기 위해 하나만 ListDecorator제공되고 (위의 클래스) 다음과 같이 할당됩니다 addDecorator:

$decor = new ListDecorator($rit);
$rit->addDecorator($decor);

그런 다음 모든 것이 설정되어 각 foreach노드를 출력합니다.

foreach($rit as $item)
{
    $inset = $decor->inset(1);
    printf("%s%s\n", $inset, $item->getName());
}

이 예제에서 볼 수 전체 출력 논리는 ListDecorator클래스 와이 단일 foreach. 전체 재귀 순회는 스택 프로 시저를 제공하는 SPL 재귀 반복으로 캡슐화되었습니다. 이는 내부적으로 재귀 호출 함수가 수행되지 않음을 의미합니다.

이벤트 기반을 ListDecorator사용하면 예시에 대해 수정하고 동일한 데이터 구조를 제공 할 수 있습니다. 배열 데이터가에 캡슐화되어 있습니다 TreeNode.

전체 코드 예 :

<?php
namespace My;

$tree = array('H' => 'G', 'F' => 'G', 'G' => 'D', 'E' => 'D', 'A' => 'E', 'B' => 'C', 'C' => 'E', 'D' => null);

// add children to parents
$flat = array(); # temporary array
foreach ($tree as $name => $parent)
{
    $flat[$name]['name'] = $name; # self
    if (NULL === $parent)
    {
        # no parent, is root element, assign it to $tree
        $tree = &$flat[$name];
    }
    else
    {
        # has parent, add self as child    
        $flat[$parent]['children'][] = &$flat[$name];
    }
}
unset($flat);

class TreeNode
{
    protected $data;
    public function __construct(array $element)
    {
        if (!isset($element['name']))
            throw new InvalidArgumentException('Element has no name.');

        if (isset($element['children']) && !is_array($element['children']))
            throw new InvalidArgumentException('Element has invalid children.');

        $this->data = $element;
    }
    public function getName()
    {
         return $this->data['name'];
    }
    public function hasChildren()
    {
        return isset($this->data['children']) && count($this->data['children']);
    }
    /**
     * @return array of child TreeNode elements 
     */
    public function getChildren()
    {        
        $children = $this->hasChildren() ? $this->data['children'] : array();
        $class = get_called_class();
        foreach($children as &$element)
        {
            $element = new $class($element);
        }
        unset($element);        
        return $children;
    }
}

class TreeNodesIterator implements \RecursiveIterator
{
    private $nodes;
    public function __construct(array $nodes)
    {
        $this->nodes = new \ArrayIterator($nodes);
    }
    public function  getInnerIterator()
    {
        return $this->nodes;
    }
    public function getChildren()
    {
        return new TreeNodesIterator($this->nodes->current()->getChildren());
    }
    public function hasChildren()
    {
        return $this->nodes->current()->hasChildren();
    }
    public function rewind()
    {
        $this->nodes->rewind();
    }
    public function valid()
    {
        return $this->nodes->valid();
    }   
    public function current()
    {
        return $this->nodes->current();
    }
    public function key()
    {
        return $this->nodes->key();
    }
    public function next()
    {
        return $this->nodes->next();
    }
}

class RecursiveListIterator extends \RecursiveIteratorIterator
{
    private $elements;
    /**
     * @var ListDecorator
     */
    private $decorator;
    public function addDecorator(ListDecorator $decorator)
    {
        $this->decorator = $decorator;
    }
    public function __construct($iterator, $mode = \RecursiveIteratorIterator::SELF_FIRST, $flags = 0)
    {
        parent::__construct($iterator, $mode, $flags);
    }
    private function event($name)
    {
        // event debug code: printf("--- %'.-20s --- (Depth: %d, Element: %d)\n", $name, $this->getDepth(), @$this->elements[$this->getDepth()]);
        $callback = array($this->decorator, $name);
        is_callable($callback) && call_user_func($callback);
    }
    public function beginElement()
    {
        $this->event('beginElement');
    }
    public function beginChildren()
    {
        $this->event('beginChildren');
    }
    public function endChildren()
    {
        $this->testEndElement();
        $this->event('endChildren');
    }
    private function testEndElement($depthOffset = 0)
    {
        $depth = $this->getDepth() + $depthOffset;      
        isset($this->elements[$depth]) || $this->elements[$depth] = 0;
        $this->elements[$depth] && $this->event('endElement');

    }
    public function nextElement()
    {
        $this->testEndElement();
        $this->event('{nextElement}');
        $this->event('beginElement');       
        $this->elements[$this->getDepth()] = 1;
    } 
    public function beginIteration()
    {
        $this->event('beginIteration');
    }
    public function endIteration()
    {
        $this->testEndElement();
        $this->event('endIteration');       
    }
}

class ListDecorator
{
    private $iterator;
    public function __construct(RecursiveListIterator $iterator)
    {
        $this->iterator = $iterator;
    }
    public function inset($add = 0)
    {
        return str_repeat('  ', $this->iterator->getDepth()*2+$add);
    }
    public function beginElement()
    {
        printf("%s<li>\n", $this->inset(1));
    }
    public function endElement()
    {
        printf("%s</li>\n", $this->inset(1));
    }
    public function beginChildren()
    {
        printf("%s<ul>\n", $this->inset());
    }
    public function endChildren()
    {
        printf("%s</ul>\n", $this->inset());
    }
    public function beginIteration()
    {
        printf("%s<ul>\n", $this->inset());
    }
    public function endIteration()
    {
        printf("%s</ul>\n", $this->inset());
    }
}


$root = new TreeNode($tree);
$it = new TreeNodesIterator(array($root));
$rit = new RecursiveListIterator($it);
$decor = new ListDecorator($rit);
$rit->addDecorator($decor);

foreach($rit as $item)
{
    $inset = $decor->inset(2);
    printf("%s%s\n", $inset, $item->getName());
}

출력 :

<ul>
  <li>
    D
    <ul>
      <li>
        G
        <ul>
          <li>
            H
          </li>
          <li>
            F
          </li>
        </ul>
      </li>
      <li>
        E
        <ul>
          </li>
          <li>
            A
          </li>
          <li>
            C
            <ul>
              <li>
                B
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

시험 (PHP 5.2 변형)

변형은 가능한 RecursiveIterator모든 이벤트를 반복하고 발생할 수있는 모든 이벤트에 대해 반복을 제공하는 반복기입니다 . 그러면 foreach 루프 내의 스위치 / 케이스가 이벤트를 처리 할 수 ​​있습니다.

관련 :


음, 먼저 키-값 쌍의 직선 배열을 배열로 바꿉니다.

function convertToHeiarchical(array $input) {
    $parents = array();
    $root = array();
    $children = array();
    foreach ($input as $item) {
        $parents[$item['id']] = &$item;
        if ($item['parent_id']) {
            if (!isset($children[$item['parent_id']])) {
                $children[$item['parent_id']] = array();
            }
            $children[$item['parent_id']][] = &$item;
        } else {
            $root = $item['id'];
        }
    }
    foreach ($parents as $id => &$item) {
        if (isset($children[$id])) {
            $item['children'] = $children[$id];
        } else {
            $item['children'] = array();
        }
    }
    return $parents[$root];
}

그러면 parent_id 및 id가있는 플랫 배열을 계층 구조로 변환 할 수 있습니다.

$item = array(
    'id' => 'A',
    'blah' => 'blah',
    'children' => array(
        array(
            'id' => 'B',
            'blah' => 'blah',
            'children' => array(
                array(
                    'id' => 'C',
                    'blah' => 'blah',
                    'children' => array(),
                ),
             ),
            'id' => 'D',
            'blah' => 'blah',
            'children' => array(
                array(
                    'id' => 'E',
                    'blah' => 'blah',
                    'children' => array(),
                ),
            ),
        ),
    ),
);

그런 다음 함수를 만듭니다.

function renderItem($item) {
    $out = "Your OUtput For Each Item Here";
    $out .= "<ul>";
    foreach ($item['children'] as $child) {
        $out .= "<li>".renderItem($child)."</li>";
    }
    $out .= "</ul>";
    return $out;
}

하지만 알렉산더-콘스탄티노 프 의 솔루션은 처음에는 쉽게 읽을 수 없습니다 수도 있습니다, 그것은 천재 기하 급수적으로 더 나은 성능의도에서,이 있었어야 최고의 답변으로 투표를 모두입니다.

감사합니다 친구,이 게시물에 제시된 두 가지 솔루션을 비교하기 위해 벤치 마크를 만들었습니다.

나는 변환해야하는 6 개의 레벨을 가진 250k 플랫 트리를 가지고 더 나은 방법을 찾고 재귀 반복을 피했습니다.

재귀 대 참조 :

// Generate a 6 level flat tree
$root = null;
$lvl1 = 13;
$lvl2 = 11;
$lvl3 = 7;
$lvl4 = 5;
$lvl5 = 3;
$lvl6 = 1;    
$flatTree = [];
for ($i = 1; $i <= 450000; $i++) {
    if ($i % 3 == 0)  { $lvl5 = $i; $flatTree[$lvl6] = $lvl5; continue; }
    if ($i % 5 == 0)  { $lvl4 = $i; $flatTree[$lvl5] = $lvl4; continue; }
    if ($i % 7 == 0)  { $lvl3 = $i; $flatTree[$lvl3] = $lvl2; continue; }
    if ($i % 11 == 0) { $lvl2 = $i; $flatTree[$lvl2] = $lvl1; continue; }
    if ($i % 13 == 0) { $lvl1 = $i; $flatTree[$lvl1] = $root; continue; }
    $lvl6 = $i;
}

echo 'Array count: ', count($flatTree), PHP_EOL;

// Reference function
function treeByReference($flatTree)
{
    $flat = [];
    $tree = [];

    foreach ($flatTree as $child => $parent) {
        if (!isset($flat[$child])) {
            $flat[$child] = [];
        }
        if (!empty($parent)) {
            $flat[$parent][$child] =& $flat[$child];
        } else {
            $tree[$child] =& $flat[$child];
        }
    }

    return $tree;
}

// Recursion function
function treeByRecursion($flatTree, $root = null)
{
    $return = [];
    foreach($flatTree as $child => $parent) {
        if ($parent == $root) {
            unset($flatTree[$child]);
            $return[$child] = treeByRecursion($flatTree, $child);
        }
    }
    return $return ?: [];
}

// Benchmark reference
$t1 = microtime(true);
$tree = treeByReference($flatTree);
echo 'Reference: ', (microtime(true) - $t1), PHP_EOL;

// Benchmark recursion
$t2 = microtime(true);
$tree = treeByRecursion($flatTree);
echo 'Recursion: ', (microtime(true) - $t2), PHP_EOL;

출력은 다음과 같이.

Array count: 255493
Reference: 0.3259289264679 (less than 0.4s)
Recursion: 6604.9865279198 (almost 2h)

UL 및 LI로 구문 분석 예측 다음과 같습니다.

$array = array (
    'H' => 'G'
    'F' => 'G'
    'G' => 'D'
    'E' => 'D'
    'A' => 'E'
    'B' => 'C'
    'C' => 'E'
    'D' => 'NULL'
);


recurse_uls ($array, 'NULL');

function recurse_uls ($array, $parent)
{
    echo '<ul>';
    foreach ($array as $c => $p)  {
        if ($p != $parent) continue;
        echo '<li>'.$c.'</li>';
        recurse_uls ($array, $c);
    }
    echo '</ul>';
}

하지만 어레이를 자주 반복 할 필요가없는 솔루션을보고 싶습니다.


내가 생각하는 것은 다음과 가변적이다.

$arr = array(
            'H' => 'G',
            'F' => 'G',
            'G' => 'D',
            'E' => 'D',
            'A' => 'E',
            'B' => 'C',
            'C' => 'E',
            'D' => null );

    $nested = parentChild($arr);
    print_r($nested);

    function parentChild(&$arr, $parent = false) {
      if( !$parent) { //initial call
         $rootKey = array_search( null, $arr);
         return array($rootKey => parentChild($arr, $rootKey));
      }else { // recursing through
        $keys = array_keys($arr, $parent);
        $piece = array();
        if($keys) { // found children, so handle them
          if( !is_array($keys) ) { // only one child
            $piece = parentChild($arr, $keys);
           }else{ // multiple children
             foreach( $keys as $key ){
               $piece[$key] = parentChild($arr, $key);
             }
           }
        }else {
           return $parent; //return the main tag (no kids)
        }
        return $piece; // return the array built via recursion
      }
    }

출력 :

Array
(
    [D] => Array
        (
            [G] => Array
                (
                    [H] => H
                    [F] => F
                )

            [E] => Array
                (
                    [A] => A
                    [C] => Array
                        (
                            [B] => B
                        )    
                )    
        )    
)

동적 트리보기 및 메뉴를 만드는 방법

1 단계 : 먼저 mysql 데이터베이스에 트 리뷰 테이블을 생성합니다. 이 테이블에는 4 개의 열이 있습니다. .id는 작업 ID이고 이름은 작업 이름입니다.

-
-- Table structure for table `treeview_items`
--

CREATE TABLE IF NOT EXISTS `treeview_items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(200) NOT NULL,
  `title` varchar(200) NOT NULL,
  `parent_id` varchar(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

--
-- Dumping data for table `treeview_items`
--

INSERT INTO `treeview_items` (`id`, `name`, `title`, `parent_id`) VALUES
(1, 'task1', 'task1title', '2'),
(2, 'task2', 'task2title', '0'),
(3, 'task3', 'task1title3', '0'),
(4, 'task4', 'task2title4', '3'),
(5, 'task4', 'task1title4', '3'),
(6, 'task5', 'task2title5', '5');

2 단계 : 트리 뷰 재귀 메서드 아래에 트리 createTreeView () 메서드를 만들었습니다.이 메서드는 현재 작업 ID가 이전 작업 ID보다 크면 재귀를 호출합니다.

function createTreeView($array, $currentParent, $currLevel = 0, $prevLevel = -1) {

foreach ($array as $categoryId => $category) {

if ($currentParent == $category['parent_id']) {                       
    if ($currLevel > $prevLevel) echo " <ol class='tree'> "; 

    if ($currLevel == $prevLevel) echo " </li> ";

    echo '<li> <label for="subfolder2">'.$category['name'].'</label> <input type="checkbox" name="subfolder2"/>';

    if ($currLevel > $prevLevel) { $prevLevel = $currLevel; }

    $currLevel++; 

    createTreeView ($array, $categoryId, $currLevel, $prevLevel);

    $currLevel--;               
    }   

}

if ($currLevel == $prevLevel) echo " </li>  </ol> ";

}

3 단계 : 보안 파일을 만들어 트리보기를 표시합니다. 이것은 트 리뷰 예제의 메인 파일입니다. 여기에서 필요한 매개 변수로 createTreeView () 메소드를 호출합니다.

 <body>
<link rel="stylesheet" type="text/css" href="_styles.css" media="screen">
<?php
mysql_connect('localhost', 'root');
mysql_select_db('test');


$qry="SELECT * FROM treeview_items";
$result=mysql_query($qry);


$arrayCategories = array();

while($row = mysql_fetch_assoc($result)){ 
 $arrayCategories[$row['id']] = array("parent_id" => $row['parent_id'], "name" =>                       
 $row['name']);   
  }
?>
<div id="content" class="general-style1">
<?php
if(mysql_num_rows($result)!=0)
{
?>
<?php 

createTreeView($arrayCategories, 0); ?>
<?php
}
?>

</div>
</body>

4 단계 : CSS 파일 style.css 만들기 여기에서는 모든 CSS 관련 클래스를 작성합니다. 현재 주문 목록을 사용하여 트리보기를 만들 수 있습니다. 여기에서 이미지 경로를 설명 수도 있습니다.

img { border: none; }
input, select, textarea, th, td { font-size: 1em; }

/* CSS Tree menu styles */
ol.tree
{
    padding: 0 0 0 30px;
    width: 300px;
}
    li 
    { 
        position: relative; 
        margin-left: -15px;
        list-style: none;
    }
    li.file
    {
        margin-left: -1px !important;
    }
        li.file a
        {
            background: url(document.png) 0 0 no-repeat;
            color: #fff;
            padding-left: 21px;
            text-decoration: none;
            display: block;
        }
        li.file a[href *= '.pdf']   { background: url(document.png) 0 0 no-repeat; }
        li.file a[href *= '.html']  { background: url(document.png) 0 0 no-repeat; }
        li.file a[href $= '.css']   { background: url(document.png) 0 0 no-repeat; }
        li.file a[href $= '.js']        { background: url(document.png) 0 0 no-repeat; }
    li input
    {
        position: absolute;
        left: 0;
        margin-left: 0;
        opacity: 0;
        z-index: 2;
        cursor: pointer;
        height: 1em;
        width: 1em;
        top: 0;
    }
        li input + ol
        {
            background: url(toggle-small-expand.png) 40px 0 no-repeat;
            margin: -0.938em 0 0 -44px; /* 15px */
            height: 1em;
        }
        li input + ol > li { display: none; margin-left: -14px !important; padding-left: 1px; }
    li label
    {
        background: url(folder-horizontal.png) 15px 1px no-repeat;
        cursor: pointer;
        display: block;
        padding-left: 37px;
    }

    li input:checked + ol
    {
        background: url(toggle-small.png) 40px 5px no-repeat;
        margin: -1.25em 0 0 -44px; /* 20px */
        padding: 1.563em 0 0 80px;
        height: auto;
    }
        li input:checked + ol > li { display: block; margin: 0 0 0.125em;  /* 2px */}
        li input:checked + ol > li:last-child { margin: 0 0 0.063em; /* 1px */ }

자세한 내용은

참고 URL : https://stackoverflow.com/questions/2915748/convert-a-series-of-parent-child-relationships-into-a-hierarchical-tree

반응형