Простой php-класс для реализации деревьев

в 8:21, , рубрики: jstree, php, деревья, класс, метки: , , ,

Здравствуйте. Я хочу рассказать о решении достаточно простой задачи, с которой я столкнулся и не сразу получил нужный результат. Необходимо реализовать дерево, источником данных для которого выступает таблица вида
Id Parent
1 Null
2 1
3 2
4 1
Т.е. каждая строка соответствует некоторому объекту с уникальным ID, и некоторые объекты имеют родителя, ID которого указан в столбце Parent. Т.е. для данного случая дерево будет иметь вид:
1
-----2
------------3
-----4
Очевидным вариантом является использование рекурсии для отображения дерева. Для каждого ID будем создавать новый экземпляр класса, поэтому нам понадобятся следующие свойства класса:

private $db; // объект для подключения к БД
public $id; // идентификатор записи
public $pt_children; // флаг наличия потомков узла дерева
public $pt_childlist; // массив, содержащий объекты класса, создаваемые для каждого узла дерева
public $pt_glub; // глубина вложенности узла

В конструкторе класса присваиваем значения указанным свойствам, затем, если у данного узла есть потомки, то обращаемся к БД и получаем строки, соответствующую заданному значению Parent. Далее создаем экземпляры класса и добавляем их в массив pt _childlist:

function __construct($db, $id, $children, $depth, $caption)
	{
		$this->db = $db;
		$this->id = $id;
		$this-> pt__children = $children;
		$this-> pt _childlist = array();
		$this-> pt_glub = $depth;
		if ($children)
		{
			$sql = "SELECT * FROM table WHERE Parent=?";
			$res = $this->db->prepare($sql);
			$val = array($id);
			$res->execute($val);
			$r = $res->fetchAll(PDO::FETCH_ASSOC);
			$j = 0;
			foreach($r as $row)
			{
				$val_ = array($row["ID"]);
				$res->execute($val_);
				if ( count($res->fetchAll(PDO::FETCH_ASSOC)) > 0 )
					$children = true;
				else
					$children = false;
				$this-> pt _childlist[$j] = new tree($db, $row["ID"], $children, $depth+1, $row["OBJ"]);
				$j++;
			}
		}
	}

Осталось реализовать метод, отображающий сформированное дерево. Для визуализации была выбрана библиотека jsTree (http://jstree.com), которая принимает данные в формате JSON. Тогда метод для отображения дерева может иметь вид:

function display($responce)
    {
        if($this-> pt_glub!= 0) // это не корневой узел
        {
            if ($this-> pt_children) // имеет потомков?
            {
                $x->data->title = $this->id;
                $x->attr->id = $this->id;
                $x->children = array();
                array_push($responce->children, $x); // добавляем их в массив
                $result = $x;
            }
            else
            {
                $x->data->title = $this->id;
                $x->attr->id = $this->id;
                $x->children = array();
                array_push($responce->children, $x);
                $result = $responce;
            }
        }
        else  // это корневой узел
        {
      $responce->data->title = $this->id;
                $responce->attr->id = $this->id;
                $responce->children = array();
                $result = $responce;
        }
        $num = sizeof($this-> pt _childlist);
        for ($j=0; $j<$num; $j++)
            $this-> pt _childlist[$j]->display($result); // проходим в цикле весь массив
        return $responce;
    }

Теперь нам осталось выбрать из базы корневые узлы и закодировать результат в JSON:

$sql = "SELECT * FROM table WHERE Parent IS NULL";
		$res = $dbo->prepare($sql);
		$res->execute();
		$r = $res->fetchAll(PDO::FETCH_ASSOC);
		$res->closeCursor();
		$i = 0;
        $result = array();
		foreach ( $r as $row )
		{
            $f = new tree ( $db, $row["Id"], true, 0, $row["Id"]);
            $result[$i] = $f->display(null);
            $i++;
		}
	echo json_encode($result);

Получается достаточно симпотично:
Простой php класс для реализации деревьев
Описание получилось сумбурным, но я думаю, основную мысль получилось показать. Спасибо за внимание.

Автор: Alf162

Источник

Поделиться

* - обязательные к заполнению поля