Короче вот метод который дёргает сам себя. PHP: public function getParentCategory($categoryID) { if (empty($this->bookCategoryName)) return false; // Сделаем запрос к бд для получения категорий $bookCategory = new Book($this->bookCategoryName); $bookCategory->where(['id' => $categoryID]); $category = $bookCategory->getFetch(); // Получаю данные о категории if ($this->test == 'unit') { echo '<pre>'; print_r($category); echo '</pre>'; } if (!empty($category)) { //$this->parent_category[$category['id']] = $category; // ложу данные array_unshift($this->parent_category, $category); // Ложу данные в начало массива $this->getParentCategory($category['parent']); } } Короче вот что я вижу когда вывожу на экран при каждом вызове рекурсии Код (Text): <pre>Array ( [id] => 76 [parent] => 71 [name_category] => 2001 [uri_category] => 2001 [link] => ford_transit##korzina_scepleniya##sceplenie##ford_transit##korzina_scepleniya##sceplenie##2001 ) </pre><pre>Array ( [id] => 71 [parent] => 69 [name_category] => ford transit [uri_category] => ford_transit [link] => sceplenie##korzina_scepleniya##ford_focus_3##ford_transit ) </pre><pre>Array ( [id] => 69 [parent] => 68 [name_category] => корзина сцепления [uri_category] => korzina_scepleniya [link] => sceplenie##korzina_scepleniya ) </pre><pre>Array ( [id] => 68 [parent] => 0 [name_category] => сцепление [uri_category] => sceplenie [link] => sceplenie ) </pre><pre></pre> А вот что я вижу когда уже собрал массив покажу два варианта один с помощью array_unshift Код (Text): <pre>Array ( [0] => Array ( [id] => 68 [parent] => 0 [name_category] => сцепление [uri_category] => sceplenie [link] => sceplenie ) [1] => Array ( [id] => 69 [parent] => 68 [name_category] => корзина сцепления [uri_category] => korzina_scepleniya [link] => sceplenie##korzina_scepleniya ) [2] => Array ( [id] => 71 [parent] => 69 [name_category] => ford transit [uri_category] => ford_transit [link] => sceplenie##korzina_scepleniya##ford_focus_3##ford_transit ) [3] => Array ( [id] => 76 [parent] => 71 [name_category] => 2001 [uri_category] => 2001 [link] => ford_transit##korzina_scepleniya##sceplenie##ford_transit##korzina_scepleniya##sceplenie##2001 ) [4] => Array ( [id] => 68 [parent] => 0 [name_category] => сцепление [uri_category] => sceplenie [link] => sceplenie ) [5] => Array ( [id] => 69 [parent] => 68 [name_category] => корзина сцепления [uri_category] => korzina_scepleniya [link] => sceplenie##korzina_scepleniya ) [6] => Array ( [id] => 71 [parent] => 69 [name_category] => ford transit [uri_category] => ford_transit [link] => sceplenie##korzina_scepleniya##ford_focus_3##ford_transit ) [7] => Array ( [id] => 68 [parent] => 0 [name_category] => сцепление [uri_category] => sceplenie [link] => sceplenie ) [8] => Array ( [id] => 69 [parent] => 68 [name_category] => корзина сцепления [uri_category] => korzina_scepleniya [link] => sceplenie##korzina_scepleniya ) [9] => Array ( [id] => 71 [parent] => 69 [name_category] => ford transit [uri_category] => ford_transit [link] => sceplenie##korzina_scepleniya##ford_focus_3##ford_transit ) ) </pre> Может я уже конечно сплю но что за магия почему их 9 ? Почему они дублируются чё не так? Теперь второй вариант это где я присваиваю сам в массив ($this->parent_category[$category['id']] = $category и в результате вижу: Код (Text): <pre>Array ( [71] => Array ( [id] => 71 [parent] => 69 [name_category] => ford transit [uri_category] => ford_transit [link] => sceplenie##korzina_scepleniya##ford_focus_3##ford_transit ) [69] => Array ( [id] => 69 [parent] => 68 [name_category] => корзина сцепления [uri_category] => korzina_scepleniya [link] => sceplenie##korzina_scepleniya ) [68] => Array ( [id] => 68 [parent] => 0 [name_category] => сцепление [uri_category] => sceplenie [link] => sceplenie ) [76] => Array ( [id] => 76 [parent] => 71 [name_category] => 2001 [uri_category] => 2001 [link] => sceplenie##korzina_scepleniya##ford_transit##2001 ) ) Вот что это за нахер, что за магия турецко китайских индусов.... Как оно может идти сначала вот так: Код (Text): ( [id] => 76 [parent] => 71 [name_category] => 2001 [uri_category] => 2001 [link] => ford_transit##korzina_scepleniya##sceplenie##ford_transit##korzina_scepleniya##sceplenie##2001 ) Это напервом месте а потом вдруг стать на последнем што это такое ваще? Где логика --- Добавлено --- Так ладно это я уже уснул, нашёл ошибку, снемите тему плиз. Не там искал просто её.
Но всё таки магия есть, смотреть два часа на рекурсию и думать о ней как чё там внутри почему не так, это как смотреть в картинку которая крутится, и тебя потихоньку начинает всасывать внутрь.
@askanim, нам препод на первом курсе говорил, что мозги у программистов бывают рекурсивные и итеративные У кого рекурсивные, тот легко хватает рекурсию.
я так понимаю, это какое-то древовидное меню, которое ты формируешь (судя по названию и по добавлению элементов в начало массива) от конечной категории к коренной?
@TeslaFeo Это в моём движке формирую ссылки для категорий. Исходя от имени каждого родителя, и не посредственно самой категории, это позволяет использовать чпу, и из чпу потом выбрать категорию, любого уровня вложенности, и при этом вероятность ошибки при одинаковых именах категорий крайне мала если только кто-то специально не начнёт кучи одинаковых категорий вводить, но тут фишка выдаст первую строку из таблицы --- Добавлено --- да именно от конечной категории к коренной. --- Добавлено --- при создании категории в движке формируется под неё уникальная ссылка с именем категории, что потом позволит мне дёргать прямо строкой из гета вот таким образом : гет строка: /sceplenie/ford-focus-3 А вот контроллер: PHP: $url = $request->getAttribute('params'); $params = explode('/', $url); $res = []; $res['uri'] = $url; $res['paramsURI'] = $params; $page = \Application\Model\Site\Pages::getPageByName('catalog'); if(!empty($page)) { $res['modules'] = $this->getModules($page['id']); $res['page_name'] = $page['name']; } $bookFacade = new FacadeBook(2); $check = $bookFacade->checkBook(); if ($check === false) { $res['type'] = 'error'; $res['text'] = 'ВСЁ ПРОПАЛО! Обратитесь в службу поддержки.'; $this->view->render($response, 'pages/catalog.php', $res); return $request; } $bookName = $bookFacade->getNameBook(); if (empty($bookName)) { $res['type'] = 'error'; $res['text'] = 'ВСЁ ПРОПАЛО! Обратитесь в службу поддержки.'; $this->view->render($response, 'pages/catalog.php', $res); return $request; } $linkCategory = implode('##', $params); $category = $bookFacade->getCategoryByLinkPath($linkCategory); if (empty($category)) { $res['type'] = 'error'; $res['text'] = 'Категории не существует!'; $this->view->render($response, 'pages/catalog.php', $res); return $request; } $res['category'] = $category; $categories = $bookFacade->getCategoryByParentID($category['id']); if (empty($categories)) { $res['products'] = $bookFacade->getElementsByCategoryID($category['id']); } else { $res['categories'] = $categories; } $this->view->render($response, 'pages/catalog.php', $res); return $request; --- Добавлено --- правда где продукты надо ещё пагинацию подрубить. --- Добавлено --- надо домодернезировать метод получения элементов внести туда лимит и возможную сортировку. --- Добавлено --- а вообще у меня есть facade для пагинации PHP: <?php /** * Created by PhpStorm. * User: strim * Date: 05.10.2017 * Time: 14:34 */ namespace Application\Modules\Facade; use Application\System\Facade\Modules\GetDataModule; use Application\System\Facade\Pagination; class GetData { /* * Функция получения данных * С пагинацией * * */ public function get($table_name, $id_page, $max_page, $order) { $countRows = GetDataModule::countQuery($table_name); $max_page = $max_page*1; $id_page = $id_page*1; $paginate = new Pagination($countRows['count_rows']*1, $id_page, 2,2, $max_page); $err = $paginate->getError(); if (!empty($err)) { $message = '';foreach ($err As $key => $value){$message .= $value;}throw new \Exception($message); } $newPageArray = $paginate->getPagination(); $first_page = $paginate->getFirst(); $last_page = $paginate->getLast(); $min = $max_page*$id_page; $min = $min-$max_page; $dataTable = GetDataModule::query($table_name, '', $order, $min, $max_page); return [ 'data' => $dataTable, 'navigation' => [ 'page_array' => $newPageArray, 'first_page' => $first_page, 'last_page' => $last_page, 'current_page' => $id_page ] ]; } } Надо его просто тоже чутка модернезировать с условием если выборка идёт по какому то определённому полю.
какой список? Это обход родителей и детей по категории. У меня безконечная вложенность в категориях. Чтобы обойти от ребёнка к родителю. Ток рекурсивно можно обойти все элементы как подругому обойти ещё если расскажешь буду знать. Потому что когда ты создаёшь в админке категорию ты имеешь не родителя на руках а имеешь лишь ребёнка. --- Добавлено --- рекурсия не обязательно должна что то возвращать
Ну да. Создаешь и указываешь родительскую категорию. Коренным указываешь parent_id = 0 Выбираешь все категории с нулём (коренные), попутно выбираешь категории, у которых parent_id == id текущей категории и выстраиваешь их в подкатегорию и т д А то, что ты задумал - я даже не могу алгоритм такой построить сходу) Там всё сложнее.
у меня не чего указывать не надо ты конкретно открываешь категорию и говоришь здесь создать ещё категорию. У меня не просто родитель ребёнок. У меня движок умеющий делать каталоги с категориями. В любом из каталогов может быть бесконечная вложенность категории, и когда пользователь захочет создать категорию ему нужно идти все id категории собирать чтобы выстроить для программы алгоритм ? забавно, программа долнжна знать сама откуда чего и куда, и я это сделал она сама всё внутри знает. --- Добавлено --- а если там 10 уровень вложенности ? --- Добавлено --- я не чего не задумал я уже всё реализовал, в движке категории создаются, на сайте пути чпу, всё окей --- Добавлено --- потом дам побаловаться движком. --- Добавлено --- когда допишу модуль в админке для соединения справочников(каталогов), с сайтами в разрез модульной системы которая там изначально стояла у меня. Пока что ручками, создаю контроллер, для вывода каталога. я его уже выше приводил. Но в скоре это ручками писать не надо будет скоро я сделаю модуль для вывода каталога.
Я не пытаюсь обесценить твои достижения. Просто мне не понятен твой подход. да хоть 50. Если не дрючить БД запросами, то для php это "ТЬФУ и растереть" --- Добавлено --- и строить ничего каждый раз не надо. Если хочешь создать подкатегорию для категории - просто указываешь первой parent_id второй.
@TeslaFeo т.есть ты предлагаешь мне выбрать все категории с парент id 0 из базы где 250 скажем категорий обойти каждую в цикле и обстроить дерево внутренних элементов при чём там надо будет отсеивать от дочернего элемента --- Добавлено --- @TeslaFeo ты не понимаешь чувак) --- Добавлено --- @TeslaFeo ты предлагаешь мне много раз в цикле обойти заместо одного запроса к бд. Со страницы сайта. Это специальная рекурсия для построения чпу ссылки которую я прямо потом из гета долбану в таблицу получу id категории что тут не понятного ? А для этого мне пришлось в админке при создании категории генерировать уникальный урл, соответствующий чпу! --- Добавлено --- я же писал создание чпу! http://ford-domodedovo.ru/ вот загляни, пока тока успел каталог реализовать, потыкай в нём посмотри на url всё поймёшь
у друпала около 200 запросов при выводе каталога, чёт он не мрёт.... А тут ну максимум 10-15 будет. --- Добавлено --- И это в админки где скорее всего более сотни не будет человек работать. И то на определённом месте и при создании новой или изменении категории и то при изменении её родителя или имени
значит друпал гавно. походу нормальных CMS вообще не существует. Качество кода прямопропорционально компетентности ЦА.
@TeslaFeo когда ты делаешь большой проект, у тебя в опреоре будет множество запросов к бд, и от того что где то происходит рекурсионный запрос по аяксу страшного не чего не случится. Серв не упадёт и мир не рухнет от 15 простых запросов к бд, которые произойдут за 0.1 мс --- Добавлено --- и даже меньше --- Добавлено --- говорю факты имею практический опыт. Не верите сами попробуйте и подумайте.
@askanim я про 200 запросов и CMS говорил. В твоём опыте не сомневаюсь) А вот в том, что ты принимаешь всё на свой счет - хорошего мало. Больно так жить.
Я тоже думаю что друпал какашка, там 50 запросов минимум на страницу приходится! --- Добавлено --- Но он хотябы в разрабокте понятен! А вот битрикс вообще лажа я вообще не могу понять как структура таблиц у него устроена, там ваще жопа на обычный инет магазин у битрикса просто около 300 таблиц в бд ет чё за ересь какая то, там ещё и по всему видимому какой то эмулятор на линуксе стоит bitrix VM что это за дичь я хз.
Зачем такая сложная рекурсия? Зачем плодить запросы к БД. Есть же Nested Sets (который, кстати, используется и в Битрикс для хранения разделов). Используя его можно одним запросом (или точнее двумя) получить сразу хоть всех родителей, хоть всех потомков, хоть соседей..... У Битрикс такое число запросов обусловлено большой гибкостью. Самый центровой модуль пока не перписали на новое ядро - очень много зависимостей. При этом многозависит от внедряющего - мне встречались сайтына которых поленившийся прочитать доку программист доводил до того, что на каждом хите выполнялось до 3тысяч запросов включая тяжелые. Приводишь все в порядок и количество запросов снижается до десятка (за исключением случая когда кеш протухает, но и вэтом случае "тысячи" - это криворучие внедряющего) bitrix VM это ни разу не эмулятор.... Естьтакое понятие как битрикс окружение. Просто linux скрипт (пакет даже) который запускаешь и он настраивает голую систему для оптимальной работы битрикс. В поседующем можно при помощи скрипта из этого пакета админить некоторые параметры. Плюсом пакет подготавливает все, чтоб можно было управлять масштабированием и кластеризацией из админки... Плюс идут готовые слепки для виртуальных машин, где уже стоит CentOS и окружение битрикс......
я знаю как сделать без рекурсии (И тема старая, уже давно переделано), мне надо было сделать быстро я сделал не ломая голову как мне сделать, Nested Sets не является лучшим решением как минимум. И в данном случае там не было вариантов сделать по другому потому что категории уже были созданы и они не копили предыдущий результат и каждая ниже рекурсия только знала кто её отец, а не всех потомков, это писалось для того чтобы как раз сделать так чтобы были уже накопленные знания о всех отцах, на существуещем каталоге.
Установи отладчик. --- Добавлено --- Это плохо. Это структура для хранения однонаправленных связных списков в БД, а не деревьев. Горя ты с этим хлебнешь еще неоднократно. Nested Sets, Materialized Path и тд не просто так придумали.
я согалсен, но я переделал. Я теперь при создании категории, записываю путь до отца. --- Добавлено --- описался, "Они не копили предыдущий результат и каждый след ребёнок знал только прямого над ним отца"