Как работают ссылки в представленном коде?
Есть массив:
$sourceArray = array( array('ID' => 705, 'NAME' => 'Телефоны и гаджеты', 'DEPTH_LEVEL' => 1), array('ID' => 706, 'NAME' => 'Смартфоны', 'DEPTH_LEVEL' => 2), array('ID' => 5586, 'NAME' => 'Аксессуары для гаджетов', 'DEPTH_LEVEL' => 2), array('ID' => 715, 'NAME' => 'Аксессуары для телефонов', 'DEPTH_LEVEL' => 3), array('ID' => 716, 'NAME' => 'Чехлы для смартфонов', 'DEPTH_LEVEL' => 4), array('ID' => 5536, 'NAME' => 'Чехлы для Apple', 'DEPTH_LEVEL' => 5), array('ID' => 5539, 'NAME' => 'Чехлы для Samsung', 'DEPTH_LEVEL' => 5), array('ID' => 3010, 'NAME' => 'Защитные стекла для телефонов', 'DEPTH_LEVEL' => 3), array('ID' => 660, 'NAME' => 'Компьютерная техника', 'DEPTH_LEVEL' => 1) ); |
$sourceArray = array( array('ID' => 705, 'NAME' => 'Телефоны и гаджеты', 'DEPTH_LEVEL' => 1), array('ID' => 706, 'NAME' => 'Смартфоны', 'DEPTH_LEVEL' => 2), array('ID' => 5586, 'NAME' => 'Аксессуары для гаджетов', 'DEPTH_LEVEL' => 2), array('ID' => 715, 'NAME' => 'Аксессуары для телефонов', 'DEPTH_LEVEL' => 3), array('ID' => 716, 'NAME' => 'Чехлы для смартфонов', 'DEPTH_LEVEL' => 4), array('ID' => 5536, 'NAME' => 'Чехлы для Apple', 'DEPTH_LEVEL' => 5), array('ID' => 5539, 'NAME' => 'Чехлы для Samsung', 'DEPTH_LEVEL' => 5), array('ID' => 3010, 'NAME' => 'Защитные стекла для телефонов', 'DEPTH_LEVEL' => 3), array('ID' => 660, 'NAME' => 'Компьютерная техника', 'DEPTH_LEVEL' => 1) );
Нужно получить древовидную структуру:
$array = array( array( 'ID' => 705, 'NAME' => 'Телефоны и гаджеты', 'DEPTH_LEVEL' => 1, 'CHILD' => array( array( 'ID' => 706, 'NAME' => 'Смартфоны', 'DEPTH_LEVEL' => 2 ), array( 'ID' => 5586, 'NAME' => 'Аксессуары для гаджетов', 'DEPTH_LEVEL' => 2, 'CHILD' => array( array( 'ID' => 715, 'NAME' => 'Аксессуары для телефонов', 'DEPTH_LEVEL' => 3, 'CHILD' => array( array( 'ID' => 716, 'NAME' => 'Чехлы для смартфонов', 'DEPTH_LEVEL' => 4, 'CHILD' => array( array( 'ID' => 5536, 'NAME' => 'Чехлы для Apple', 'DEPTH_LEVEL' => 5 ), array( 'ID' => 5539, 'NAME' => 'Чехлы для Samsung', 'DEPTH_LEVEL' => 5 ) ) ), array( 'ID' => 3010, 'NAME' => 'Защитные стекла для телефонов', 'DEPTH_LEVEL' => 4, 'SECTION_PAGE_PATH_TEMPLATE' => '#SITE_DIR#/catalog/#SECTION_CODE_PATH#/' ) ) ) ) ) ) ), array( 'ID' => 660, 'NAME' => 'Компьютерная техника', 'DEPTH_LEVEL' => 1 ) ); |
$array = array( array( 'ID' => 705, 'NAME' => 'Телефоны и гаджеты', 'DEPTH_LEVEL' => 1, 'CHILD' => array( array( 'ID' => 706, 'NAME' => 'Смартфоны', 'DEPTH_LEVEL' => 2 ), array( 'ID' => 5586, 'NAME' => 'Аксессуары для гаджетов', 'DEPTH_LEVEL' => 2, 'CHILD' => array( array( 'ID' => 715, 'NAME' => 'Аксессуары для телефонов', 'DEPTH_LEVEL' => 3, 'CHILD' => array( array( 'ID' => 716, 'NAME' => 'Чехлы для смартфонов', 'DEPTH_LEVEL' => 4, 'CHILD' => array( array( 'ID' => 5536, 'NAME' => 'Чехлы для Apple', 'DEPTH_LEVEL' => 5 ), array( 'ID' => 5539, 'NAME' => 'Чехлы для Samsung', 'DEPTH_LEVEL' => 5 ) ) ), array( 'ID' => 3010, 'NAME' => 'Защитные стекла для телефонов', 'DEPTH_LEVEL' => 4, 'SECTION_PAGE_PATH_TEMPLATE' => '#SITE_DIR#/catalog/#SECTION_CODE_PATH#/' ) ) ) ) ) ) ), array( 'ID' => 660, 'NAME' => 'Компьютерная техника', 'DEPTH_LEVEL' => 1 ) );
Вот решение, где dbAllSections содержит в себе все разделы. Оно работает, но я никак понять не могу, зачем тут делать $node = &$tree; и $node = &$node[$ancestor['INDEX']]['CHILDREN'];. Ссылки же говорят, что другая переменная будет ссылаться на то же значение, но для чего делать $node = &$tree; каждую итерацию, если они и так ссылаются на одно значение. Зачем делать $node = &$node[$ancestor['INDEX']]['CHILDREN']; тоже не понятно.
Для удобства https://3v4l.org/RPkHb
$tree = []; $stack = []; while ($item = $dbAllSections->fetch()) { $node = &$tree; while (!empty($stack) && $stack[count($stack) - 1]['DEPTH_LEVEL'] >= $item['DEPTH_LEVEL']) { array_pop($stack); } foreach ($stack as $ancestor) { $node = &$node[$ancestor['INDEX']]['CHILDREN']; } $node[] = [ 'ID' => $item['ID'], 'NAME' => $item['NAME'] ]; $stack[] = [ 'INDEX' => count($node) - 1, 'DEPTH_LEVEL' => $item['DEPTH_LEVEL'], ]; } |
$tree = []; $stack = []; while ($item = $dbAllSections->fetch()) { $node = &$tree; while (!empty($stack) && $stack[count($stack) - 1]['DEPTH_LEVEL'] >= $item['DEPTH_LEVEL']) { array_pop($stack); } foreach ($stack as $ancestor) { $node = &$node[$ancestor['INDEX']]['CHILDREN']; } $node[] = [ 'ID' => $item['ID'], 'NAME' => $item['NAME'] ]; $stack[] = [ 'INDEX' => count($node) - 1, 'DEPTH_LEVEL' => $item['DEPTH_LEVEL'], ]; }
Дополнительно:
По придурковатому виду кода предположу что это битрикс... В тегах указывайте битрикс, чтобы нормальные люди не пугались, ну и битриксоиды находили быстрее ваш вопрос...
Зачем автор кода их вписал - неизвестно, видимо была причина.
Закомментируйте и проверьте работу кода, вот и всё.
https://3v4l.org/RPkHb
function buildTree($data) { $tree = []; // Результирующее дерево $stack = []; // Стек для отслеживания предыдущих уровней foreach ($data as $item) { $node = &$tree; // Удаляем из стека элементы с уровнем глубже текущего while (!empty($stack) && $stack[count($stack) - 1]['DEPTH_LEVEL'] >= $item['DEPTH_LEVEL']) { array_pop($stack); } // Переходим по уровням для поиска нужного места в дереве foreach ($stack as $ancestor) { $node = &$node[$ancestor['INDEX']]['CHILDREN']; } // Добавляем текущий элемент в дерево $node[] = [ 'ID' => $item['ID'], 'NAME' => $item['NAME'] ]; // Запоминаем текущий уровень и индекс для последующих элементов $stack[] = [ 'INDEX' => count($node) - 1, 'DEPTH_LEVEL' => $item['DEPTH_LEVEL'], ]; } return $tree; } |
function buildTree($data) { $tree = []; // Результирующее дерево $stack = []; // Стек для отслеживания предыдущих уровней foreach ($data as $item) { $node = &$tree; // Удаляем из стека элементы с уровнем глубже текущего while (!empty($stack) && $stack[count($stack) - 1]['DEPTH_LEVEL'] >= $item['DEPTH_LEVEL']) { array_pop($stack); } // Переходим по уровням для поиска нужного места в дереве foreach ($stack as $ancestor) { $node = &$node[$ancestor['INDEX']]['CHILDREN']; } // Добавляем текущий элемент в дерево $node[] = [ 'ID' => $item['ID'], 'NAME' => $item['NAME'] ]; // Запоминаем текущий уровень и индекс для последующих элементов $stack[] = [ 'INDEX' => count($node) - 1, 'DEPTH_LEVEL' => $item['DEPTH_LEVEL'], ]; } return $tree; }
foreach ($data as $item): Проходим по каждому элементу исходного массива.
$node = &$tree;: Инициализируем переменную $node ссылкой на корень дерева.
while (!empty($stack) && $stack[count($stack) - 1]['DEPTH_LEVEL'] >= $item['DEPTH_LEVEL']): Убираем из стека элементы, уровень глубины которых больше или равен текущему уровню.
foreach ($stack as $ancestor): Переходим по уровням дерева согласно стеку для нахождения места вставки текущего элемента.
$node[] = [...]: Добавляем текущий элемент в дерево.
$stack[] = [...]: Записываем текущий уровень и индекс элемента для последующих элементов.
Но все равно не понятно, как мы инициализируем переменную $node ссылкой на корень дерева, если дерево хранит все дерево. При чем тут ссылки?
$tree = []; $stack = []; while ($item = $dbAllSections->fetch()) { while (!empty($stack) && $stack[count($stack) - 1]['DEPTH_LEVEL'] >= $item['DEPTH_LEVEL']) { array_pop($stack); } $index=end($stack)['INDEX']; $tree[$index]['CHILDREN'][] = [ 'ID' => $item['ID'], 'NAME' => $item['NAME'] ]; $stack[] = [ 'INDEX' => count($tree[$index]) - 1, 'DEPTH_LEVEL' => $item['DEPTH_LEVEL'], ]; } |
$tree = []; $stack = []; while ($item = $dbAllSections->fetch()) { while (!empty($stack) && $stack[count($stack) - 1]['DEPTH_LEVEL'] >= $item['DEPTH_LEVEL']) { array_pop($stack); } $index=end($stack)['INDEX']; $tree[$index]['CHILDREN'][] = [ 'ID' => $item['ID'], 'NAME' => $item['NAME'] ]; $stack[] = [ 'INDEX' => count($tree[$index]) - 1, 'DEPTH_LEVEL' => $item['DEPTH_LEVEL'], ]; }
поправил
$node = &$node[$ancestor['INDEX']]['CHILDREN']; ссылка на нужный массив из дерева.
$node[] = [ добавление в дерево
'INDEX' => count($node) - 1, добавление в стэк. только count($node[$ancestor['INDEX']]['CHILDREN'])-1
Такой оригинальный способ рекурсии.
Ответы:
думаю все эксперты согласятся что правильный ответ "через ж..пу"...
Если этот массив получен из CIBlockSection::GetList, попробуйте получить помимо DEPTH_LEVEL, еще LEFT_MARGIN и RIGHT_MARGIN. И по ветвям уже из массива можно будет построить дерево.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для создания ссылок в HTML коде необходимо использовать тег ``. Этот тег имеет атрибут `href`, который определяет URL-адрес, на который будет переходить пользователь при нажатии на ссылку.
Пример создания ссылки в HTML коде:
<a href="https://www.example.com">Нажми меня</a>
В данном примере при клике на текст "Нажми меня" пользователь будет перенаправлен на сайт https://www.example.com.
Также можно добавить атрибут `target="_blank"`, чтобы ссылка открывалась в новой вкладке браузера:
<a href="https://www.example.com" target="_blank">Нажми меня</a>
Этот код позволит открыть ссылку в новой вкладке, чтобы пользователь не покидал текущую страницу.
Для создания ссылок в PHP можно использовать аналогичный код, который будет генерировать HTML код:
$url = "https://www.example.com"; $text = "Нажми меня"; echo "<a href='$url'>$text</a>";
Этот PHP код также создаст ссылку с текстом "Нажми меня", ведущую на https://www.example.com.
Таким образом, ссылки в HTML и PHP работают путем определения URL-адреса в атрибуте `href` тега ``, который перенаправляет пользователя на указанный сайт при клике.