Простой 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); 

Получается достаточно симпотично:

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

ссылка на оригинал статьи http://habrahabr.ru/post/171053/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *