Я пытаюсь построить иерархический массив в PHP из содержимого реляционной базы данных, которое хранится с использованием таблицы закрытия. Для данного результата у меня будет полный путь к узлу LEAF
, приведенный ниже будет выглядеть как мой набор результатов.
1 ~корень ~корневой узел
1 ~корень ~корневой узел>>>2 ~категория 1 ~Первая категория
1 ~корень ~корневой узел>>>3 ~категория 2 ~Вторая категория
1 ~root ~корневой узел>>>2 ~категория1 ~Первая категория>>>4 ~subCatOfCategory1 ~Подкатегория категории 1
Во всяком случае, это результаты моей базы данных. Поэтому я хочу обойти их и построить иерархическую структуру на PHP, чтобы я мог преобразовать ее в JSON и отобразить дерево в DOJO
. Итак, когда я просматриваю каждую строку, я строю «путь» к листу, потому что мне нужно добавить элемент в дерево только тогда, когда элемент является «листом»... Размышляя над этим, я решил, что буду токенизировать каждый результат., используя «>>>» в качестве разделителя, что дает мне узлы, которые находятся в этой строке. Затем я перебираю эти узлы, токенизируя каждый из них с помощью " ~", что дает мне атрибуты каждого узла.
Итак, у меня есть цикл for для обработки каждой ROW, и он в основном определяет, что если обрабатываемый узел НЕ является листом, добавьте его идентификатор в массив, который должен отслеживать путь к конечному листу, который будет обработан. ТОГДА, когда я, наконец, доберусь до LEAF, я могу вызвать функцию для вставки узла, используя PATH, который я скомпилировал по пути.
Надеюсь, все понятно... поэтому я включил приведенный ниже код. Рассмотрим второй результат сверху.Когда я обработал весь этот результат и собираюсь вызвать функцию insertNodeInTreeV2 (), массивы выглядят следующим образом...
$fullTree
представляет собой массив с 1 элементом, проиндексированным как [1] Этот элемент содержит массив из четырех элементов:ID(1)
, NAME(root)
, Description(the root node)
,CHILDREN(empty array)
$pathEntries
представляет собой массив только с одним элементом, (1 ). Это означает, что PATH к вставляемому узлу LEAF относится к узлу [1], который является корневым узлом.
$nodeToInsert
представляет собой массив из четырех элементов:ID(2)
, NAME(category1)
, Description(First Category)
,CHILDREN(empty array)
$treeRootPattern
представляет собой STRING, который содержит имя переменной, которое я использую для хранения всего массива/дерева, которое в данном случае является «fullTree».
private function insertNodeInTreeV2( array &$fullTree, array $pathEntries, array $nodeToInsert, $treeRootPattern )
{
$compiledPath = null;
foreach ( $pathEntries as $path ) {
$compiledPath.= $treeRootPattern. '['. $path. '][\'CHILDREN\']';
}
// as this point $compiledPath = "fullTree[1]['CHILDREN']"
$treeVar = $$compiledPath;
}
Поэтому, когда я делаю присвоение $treeVar = $$compiledPath;, Я ДУМАЮ, что устанавливаю переменную $treeVar равной $fullTree[1]['CHILDREN'] (, которую я проверил в своем отладчике. допустимый индекс массива ). Даже если я вставлю содержимое $compiledPath в новое выражение в отладчике Eclipse, он покажет мне пустой массив, что имеет смысл, поскольку именно он находится в $fullTree[1]['CHILDREN']
Но вместо этого среда выполнения сообщает мне следующую ошибку...
troller.php line 85 - Undefined variable: fullTree[1]['CHILDREN']
Любая помощь в этом будет принята с благодарностью... И если у вас есть лучший способ для меня получить из набора результатов, который я описал, иерархический массив, который я пытаюсь построить, я бы очень хотел принять лучший метод.
ОБНОВЛЕНО, ДОБАВЛЕНО КОД, ВЫЗЫВАЮЩИЙ ВЫШЕУКАЗАННУЮ ФУНКЦИЮ --РЕЗУЛЬТАТЫ РЕЗУЛЬТАТОВ БАЗЫ ДАННЫХ, ОПИСАННЫЕ ВЫШЕ, ДЛЯ ЦИКЛОВ FOR LOOP
foreach ( $ontologyEntries as $entry ) {
// iterating over rows of '1~~root~~The root node>>>2~~category1~~The first category
$nodes = explode( '>>>', $entry['path'] );
$numNodes = count( $nodes ) - 1 ;
$pathToNewNode = null; // this is the path, based on ID, to get to this *new* node
for ( $level = 0; $level <= $numNodes; $level++ ) {
// Parse the node out of the database search result
$thisNode = array(
'ID' => strtok($nodes[$level], '~~'), /* 1 */
'NAME' => strtok( '~~'), /* Root */
'DESCRIPTION' => strtok( '~~'), /* This is the root node */
'CHILDREN' => array()
);
if ( $level < $numNodes ) { // Not a leaf, add it to the pathToThisNodeArray
$pathToNewNode[] = $thisNode['ID'];
}
else {
// processing a leaf, add it to the array
$this->insertNodeInTreeV2( $$treeRootPattern, $pathToNewNode, $thisNode, $treeRootPattern );
}
}
}