Как работают ссылки в представленном коде?

Ссылка скопирована
2 февраля 2026 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) );

$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'], ]; }

Дополнительно:

По придурковатому виду кода предположу что это битрикс... В тегах указывайте битрикс, чтобы нормальные люди не пугались, ну и битриксоиды находили быстрее ваш вопрос...

  • IMHO эти две ссылки никак не работают, потому что нигде не используются.
    Зачем автор кода их вписал - неизвестно, видимо была причина.
    Закомментируйте и проверьте работу кода, вот и всё.
  • AUser0, без ссылок код не работает https://3v4l.org/tr1s3
  • ThunderCat, я понимаю, но тут вопрос не только битриксойдам, так как битрикса это касается косвенно. Если честно эту часть кода я получил от ChatGBT, но я не могу понять как этот способ работает
    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'], ]; }

    поправил

  • iljaGolubev, выше есть его ответ, но я не понял, из-за этого задал вопрос на форуме
  • iljaGolubev, не работает https://3v4l.org/GgjoI
  • $node = &$tree; для каждого итема ссылка на всё дерево.
    $node = &$node[$ancestor['INDEX']]['CHILDREN']; ссылка на нужный массив из дерева.
    $node[] = [ добавление в дерево
    'INDEX' => count($node) - 1, добавление в стэк. только count($node[$ancestor['INDEX']]['CHILDREN'])-1

    Такой оригинальный способ рекурсии.

  • ant123455432143, Вопрос не в том что это код для битрикс или не для битрикс. Структура ссылок в изначальном массиве уже идиотская, в частности не содержит ключей, указывающих на принадлежность одних итемов другим, как в нормальном nested sets, а опирается только на порядок представления и глубину вложенности. Для нормального связанного списка есть вполне простая рекурсивная метода посторения дерева из списка, а тут все через пятую точку. По этому вроде как да, можно сесть поупражняться, но как бы единственный возможный ответ - готовый код, а в таком случае пусть уж битриксоиды со своей привычкой нестандартно любиться страдают...
  • Ответы:

    думаю все эксперты согласятся что правильный ответ "через ж..пу"...

    Если этот массив получен из CIBlockSection::GetList, попробуйте получить помимо DEPTH_LEVEL, еще LEFT_MARGIN и RIGHT_MARGIN. И по ветвям уже из массива можно будет построить дерево.

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Виктор Sys Ответ

    Для создания ссылок в HTML коде необходимо использовать тег ``. Этот тег имеет атрибут `href`, который определяет URL-адрес, на который будет переходить пользователь при нажатии на ссылку.

    Пример создания ссылки в HTML коде:

    <a href="https://www.example.com">Нажми меня</a>

    <a href="https://www.example.com">Нажми меня</a>

    В данном примере при клике на текст "Нажми меня" пользователь будет перенаправлен на сайт https://www.example.com.

    Также можно добавить атрибут `target="_blank"`, чтобы ссылка открывалась в новой вкладке браузера:

    <a href="https://www.example.com" target="_blank">Нажми меня</a>

    <a href="https://www.example.com" target="_blank">Нажми меня</a>

    Этот код позволит открыть ссылку в новой вкладке, чтобы пользователь не покидал текущую страницу.

    Для создания ссылок в PHP можно использовать аналогичный код, который будет генерировать HTML код:

    $url = "https://www.example.com";
    $text = "Нажми меня";
    echo "<a href='$url'>$text</a>";

    $url = "https://www.example.com"; $text = "Нажми меня"; echo "<a href='$url'>$text</a>";

    Этот PHP код также создаст ссылку с текстом "Нажми меня", ведущую на https://www.example.com.

    Таким образом, ссылки в HTML и PHP работают путем определения URL-адреса в атрибуте `href` тега ``, который перенаправляет пользователя на указанный сайт при клике.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

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

    Вам также может быть интересно