Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Wielopoziomowe menu rekurencja
troian
post 12.09.2017, 11:51:17
Post #1





Grupa: Zarejestrowani
Postów: 184
Pomógł: 2
Dołączył: 3.02.2013

Ostrzeżenie: (0%)
-----


Witam, od jakiegoś czas główkuję nad rozwiązaniem problemu wielopoziomowego menu generowanego na podstawie bazy, chodzi mi o coś w tym stylu:
<ul>
<li>1</li>
<li>2
<ul>
<li>2-1</li>
<li>2-2
<ul>
<li>2-2-1</li>
<li>2-2-2</li>
</ul>
</li>
</ul>
<li>
</ul>

struktura bazy danych wyglądała by następująca:
ID | PARENT_ID | NAME |
1 | 0 | 1 |
2 | 0 | 2 |
3 | 2 | 2-1 |
4 | 2 | 2-2 |
5 | 4 | 2-2-1 |
6 | 4 | 2-2-2 |

wiem że mógłbym wykorzystać rekurencje która przy każdym powtórzeniu wyszukiwała by coraz niższego poziomu drzewa zaczynając od 0, jednak jeżeli będę miał 10 opcji, w każdej po 5 podopcji i jeszcze w co 2 podopcji kolejne dwie to naglę ilość zapytań do bazy będzie astronomiczna, a to tylko podczas rysowania samego menu, dlatego chce wykonać 1 zapytanie za pomocą którego pobieram całą bazę i zrzucam ją do tablicy i na niej chce operować, jednak wszystkie próby moje napisania tego kończyły się komunikatem Fatal error: Allowed memory size of 536870912 bytes exhausted. Nie mam bladego pojęcia jak podejść do tego w taki sposób aby nie powstała mi wieczna pętla. Szukałem różnych rozwiązań wykorzystujących rekurencje jednak znaczna ilość z nich operowała na takiej oto strukturze:
  1. 0 => array('id' => 1, 'name' => 'nazwa', 'sub' => array(tutaj tablica zagnieżdżonego subMenu));


Jeżeli ktoś zna gotowy przykład albo chociaż coś na bazie czego mógłbym napisać sobie taką funkcję to bardzo proszę o pomoc smile.gif



Go to the top of the page
+Quote Post
Pyton_000
post 12.09.2017, 11:54:15
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


https://stackoverflow.com/questions/4196157...from-array-list
Go to the top of the page
+Quote Post
troian
post 12.09.2017, 12:26:27
Post #3





Grupa: Zarejestrowani
Postów: 184
Pomógł: 2
Dołączył: 3.02.2013

Ostrzeżenie: (0%)
-----


Cytat(Pyton_000 @ 12.09.2017, 12:54:15 ) *


no rozwiązanie też trochę słabe bo aby zbudować całe menu musiałem przerobić to w taki oto sposób:
  1. $arr = array(
  2. array('id'=>1, 'parent_id'=>0, 'name'=>'1'),
  3. array('id'=>2, 'parent_id'=>0, 'name'=>'2'),
  4. array('id'=>3, 'parent_id'=>1, 'name'=>'11'),
  5. array('id'=>4, 'parent_id'=>1, 'name'=>'12'),
  6. array('id'=>5, 'parent_id'=>4, 'name'=>'121'),
  7. array('id'=>6, 'parent_id'=>4, 'name'=>'122'),
  8. array('id'=>7, 'parent_id'=>0, 'name'=>'3'),
  9. array('id'=>8, 'parent_id'=>0, 'name'=>'4'),
  10. );
  11.  
  12. function createSub(&$list, $parent){
  13. $tree = array();
  14. foreach ($parent as $k=>$l){
  15. if(isset($list[$l['id']])){
  16. $l['children'] = createSub($list, $list[$l['id']]);
  17. }
  18. $tree[] = $l;
  19. }
  20. return $tree;
  21. }
  22.  
  23. function createMenu($data)
  24. {
  25. $temp = array();
  26. $tree = array();
  27. foreach ($data as $key=>$value)
  28. {
  29. $temp[$value['parent_id']][] = $value;
  30. }
  31. foreach($data as $key=>$value)
  32. {
  33. if ($value['parent_id'] == 0)
  34. {
  35. $tree[] = createSub($temp, array($data[$key]));
  36. }
  37. }
  38. return $tree;
  39. }


przy bazie np 50 rekordów trochę słabo widzę wydajność tego + jeszcze trzeba by dopisać 3 funkcję która zbuduje na podstawie takiej tabeli kod html i tutaj też będzie potrzebna rekurencja.

Ten post edytował troian 12.09.2017, 12:30:38
Go to the top of the page
+Quote Post
Pyton_000
post 12.09.2017, 13:04:33
Post #4





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Ale jaki masz problem? Masz typowy use case gdzie masz zbudować menu na podstawie tablicy id-parent_id. Jest pełno w sieci rozwiązań jak to zbudować. To co Ci podesłałem to jeden z przykładów i tam też jest wiele rozwiązań.

Może lepiej napisz dokładnie czego chcesz?
Go to the top of the page
+Quote Post
troian
post 13.09.2017, 07:37:08
Post #5





Grupa: Zarejestrowani
Postów: 184
Pomógł: 2
Dołączył: 3.02.2013

Ostrzeżenie: (0%)
-----


Cytat(Pyton_000 @ 12.09.2017, 14:04:33 ) *
Ale jaki masz problem? Masz typowy use case gdzie masz zbudować menu na podstawie tablicy id-parent_id. Jest pełno w sieci rozwiązań jak to zbudować. To co Ci podesłałem to jeden z przykładów i tam też jest wiele rozwiązań.

Może lepiej napisz dokładnie czego chcesz?


Masz rację jednak ja albo jestem jakiś nie... albo nie potrafię korzystać z google smile.gif Chodzi mi o coś podobnego do tego co mi zaprezentowałeś tylko operującego np na 1 funkcji oraz 1 zmiennej do której zapisuje zrzut struktury z sql, rozwiązanie podane UP nie jest złe tylko boje się że przy dużym menu zacznie po prostu nie potrzebnie marnować zasoby serwera, jeżeli się mylę to mnie popraw.

Chciałem napisać coś na takiej zasadzie:

function menu($id=0)
{
$data = $this->data; // tutaj znajduje sie cala tablica menu pobrana wcześniej z sql
forech($data as $key=>$value) [...] i bezpośrednio budować menu w postaci html <ul><li> itd... i w przypadku w którym natrafia np na $value->parent_id wykonuje jeszcze raz funkcje $this->menu($this->parent_id); tylko w żaden sposób nie potrafię wymyślisz jak powinna wyglądać taka funkcja aby prawidłowo operowała na bazie i generowała wyjściowy kod html
}

edit;

Udało mi się napisać skrypt który działa w oparciu o 2 funkcję oto moje dzieło:
  1. function menusql($id)
  2. {
  3. $arr = (object) array(
  4. (object) array('id'=>1, 'parent_id'=>0, 'name'=>'1'),
  5. (object) array('id'=>2, 'parent_id'=>0, 'name'=>'2'),
  6. (object) array('id'=>3, 'parent_id'=>1, 'name'=>'11'),
  7. (object) array('id'=>4, 'parent_id'=>1, 'name'=>'12'),
  8. (object) array('id'=>5, 'parent_id'=>4, 'name'=>'121'),
  9. (object) array('id'=>6, 'parent_id'=>4, 'name'=>'122'),
  10. (object) array('id'=>9, 'parent_id'=>6, 'name'=>'1221'),
  11. (object) array('id'=>7, 'parent_id'=>0, 'name'=>'3'),
  12. (object) array('id'=>8, 'parent_id'=>0, 'name'=>'4'),
  13. );
  14.  
  15. $temp = array();
  16.  
  17. foreach($arr as $key=>$value)
  18. {
  19. if ($value->parent_id == $id)
  20. {
  21. $temp[] = $value;
  22. }
  23. }
  24. return $temp;
  25. }
  26.  
  27.  
  28. function tree($id_parent)
  29. {
  30. $data = menusql($id_parent);
  31. $html = '<ul>';
  32. foreach($data as $key=>$value)
  33. {
  34. $html .= '<li><a href="article/'.$value->id.'">'.$value->name.'</a>';
  35. $child = menusql($value->id);
  36. if (count($child) > 0)
  37. {
  38. $html .= tree($value->id);
  39. }
  40. $html .= '</li>';
  41. }
  42. $html .= '</ul>';
  43. return $html;
  44. }
  45.  
  46. echo tree(0);


Pewnie szło by to zrobić lepiej ale ważne że działa, może komuś się przyda to zostawię to tutaj

Ten post edytował troian 13.09.2017, 11:19:16
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 27.04.2024 - 06:45