Здравствуйте. Я хочу рассказать о решении достаточно простой задачи, с которой я столкнулся и не сразу получил нужный результат. Необходимо реализовать дерево, источником данных для которого выступает таблица вида
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);
Получается достаточно симпотично:
Описание получилось сумбурным, но я думаю, основную мысль получилось показать. Спасибо за внимание.
Автор: Alf162