[PHP] Gnezdenje

Z Recursive functions sem uredil tako, da ima lahko kategorija "neomejeno" podkategorij in vsaka podkategorija še dodatne podkategorije itd. Zdaj me pa zanima ali obstaja kakšen boljši način takšnega gnezdenja kot da uporabim recursive function? Težave je, ker je na strežniku omejitev za gnezdenje, določen je "Maximum function nesting level of '100'" in ko je ta limit dosežen, se skripta ustavi. A dam limit na, ne vem, 10.000 in pozabim na vse skupaj ali obstaja kakšen boljši način?

20 odgovorov

za začetek daj v to rekurzivno funkcijo kakšen pogoj, kdaj gre ven iz loopa, pa ne bo treba zmanjševat

Mogoče nisem najbolj jasno napisal :) Saj koda deluje in jasno je notri tudi pogoj, da gre ven iz loopa ampak teoretično, če bi imel v bazi veliko kategorij in znotraj gnezdenih podpodpod..podkategorij, bi pač lahko prišlo do maximuma 100 in me zanima, če obstaja kakšen boljši način?

Recimo tule bi rekel, da je nesting level nad 100, če so slučajno delali z recursive function https://www.reddit.com/r/gaming/comments/3ae8qw/newdoomwitholdcolors/?limit=500

Pa saj se ne bi ne vem kako sekiral ampak zadevo, ki jo delam, bodo izpolnjevali uporabniki in potem nikol ne veš, v kakšne vse globine bodo lahko šli.

hm.. nevem kako si ti to zložil skupaj in kdo ali kaj ti določi "nesting level" ??

Glede na to da imaš neke kategorije, sklepam da uporabljaš neko bazo za te kategorije Se pravi če ima vsaka kategorija nek svoj ID in da ima poleg še parent ID ... potem ne igra nobene vloge koliko kategorij obstaja, koliko jih je pod določeno in koliko globoko gredo ? Rekurzivna funkcija ti v takem primeru služi samo za iskanje parenta X nivojev navzgor ... v globino več kot par nivojev pa ni smiselno it oz. če moraš pomeni da si slabo zastavil logiko. Verjetno ne razumem najbolje kaj sploh počneš in kje oz. kaj je ta nesting level :)

1

theuros:
hm.. nevem kako si ti to zložil skupaj in kdo ali kaj ti določi "nesting level" ??

Glede na to da imaš neke kategorije, sklepam da uporabljaš neko bazo za te kategorije Se pravi če ima vsaka kategorija nek svoj ID in da ima poleg še parent ID ... potem ne igra nobene vloge koliko kategorij obstaja, koliko jih je pod določeno in koliko globoko gredo ? Rekurzivna funkcija ti v takem primeru služi samo za iskanje parenta X nivojev navzgor ... v globino več kot par nivojev pa ni smiselno it oz. če moraš pomeni da si slabo zastavil logiko. Verjetno ne razumem najbolje kaj sploh počneš in kje oz. kaj je ta nesting level :)

Približno tako imam, ja. Kategorija ma svoj id in parent_id. Če so samo kategorije, potem se jasno Recursive funkcija ne kliče vendar, če pa imam na primer 50 kategorij, vsaka ima še svojo podkategorijo in ta še eno podkategorijo, se pa Recursive kliče 100x in smo že pri default omejitvi in se izpiše napaka. Saj teoretično je to kar težko doseči ampak glede na to, da planiram, da bodo zadevo izpolnjevali uporabniki, nikoli ne veš, kdaj se bo našel kdo, ki bo malo "pretiraval" zato sprašujem, če obstaja kak elegantnejši način, kako nalogo rešiti, da bi se lahko izognil tej default nesting level omejitvi.

Tako kot je napisal uroš, rekurzijo boš rabil samo v metodah getParent() in getChildren()... In ta tvoja omejitev bo prišla do izraza samo če bojo tvoji uporabniki vgnezdili 100 kategorij, torej bi nek menu moral imeti 100 nivojev, halo? Mislim pa da so redki ki rabijo vgnezdenje več kot 5 nivojev...
Če želiš biti programer, moraš biti pragmatičen, sicer boš zgubljal preveč časa na neumnostih

11

Ni nujno, da ima nek meni 100 nivojev, vsaj pri moji skripti ne, če imaš 50 kategorij in ima vsak podkategorijo, se recursive kliče že 50x, ker mora za vsak podmeni pač kreirat nov meni. Sem pa omenil, da bodo rešitev uporabljali uporabniki in pri njih nikoli ne veš. Evo ti primer ene naključne strani... http://cult-trgovina.si/si/. Če imajo to rešeno z recursive, se ta kliče več kot 100x in php bi v tem primeru izpisal error (če bi ostala "default Maximum function nesting level of 100"). Tko da tale "halo?" lahko postane realnost :P

thai:
Če so samo kategorije, potem se jasno Recursive funkcija ne kliče

thai:
če pa imam na primer 50 kategorij, vsaka ima še svojo podkategorijo in ta še eno podkategorijo, se pa Recursive kliče 100x

Če so samo kategorije se recursive ne kliče, če pa so podkategorije pa se ?? .. kaj podkategorija ni kategorija ?

Prosim napiši praktičen primer kaj dejansko delaš, saj iz te razlage ni nič jasno. Kaj mogoče vsaka kategorija vsebuje X število člankov ali kakšnih izdelkov in zdaj tebe skrbi, da če bi hotel izpisati vse članke ali izdelke iz večjega števila gnezdenih kategorij, da bi se ti ta funkcija obesla oz. šla v timeout ?

Pa glede "default nesting level" ... to mi še vedno ni jasno kaj je ???? funkcija lahko gre v timeout če deluje preveč časa neglede in v tem času se lahko izvede 10x, 100x ali 1000x ..

thai:
Ni nujno, da ima nek meni 100 nivojev, vsaj pri moji skripti ne, če imaš 50 kategorij in ima vsak podkategorijo, se recursive kliče že 50x, ker mora za vsak podmeni pač kreirat nov meni. Sem pa omenil, da bodo rešitev uporabljali uporabniki in pri njih nikoli ne veš. Evo ti primer ene naključne strani... http://cult-trgovina.si/si/. Če imajo to rešeno z recursive, se ta kliče več kot 100x in php bi v tem primeru izpisal error (če bi ostala "default Maximum function nesting level of 100"). Tko da tale "halo?" lahko postane realnost :P

Očitno ti gradiš nek menu iz kategorij ki jih imaš .. ko se kreira prvi nivo greš za vsako kategorijo pogledat če ima podkategorijo in prikažeš še te .. in tako v nedogled v globino kolikor jih obstaja.

Kategorij ne sme biti toliko da bi se ti funkcija obesla .... pa če tudi .. še vedno lahko postopoma zlagaš meni in ne vsega naenkrat, ... pa tudi vse skupaj vržeš v cache tako da se ne izvede ob vsakem requestu ..

Vseh kategorij nima smisla imet na enkrat odprtih, tako da prikažeš samo aktivne in na klik izdeveš kak ajax da ti pokaže še podkategorije.

theuros:

thai:
Če so samo kategorije, potem se jasno Recursive funkcija ne kliče

thai:
če pa imam na primer 50 kategorij, vsaka ima še svojo podkategorijo in ta še eno podkategorijo, se pa Recursive kliče 100x

Če so samo kategorije se recursive ne kliče, če pa so podkategorije pa se ?? .. kaj podkategorija ni kategorija ?

Prosim napiši praktičen primer kaj dejansko delaš, saj iz te razlage ni nič jasno. Kaj mogoče vsaka kategorija vsebuje X število člankov ali kakšnih izdelkov in zdaj tebe skrbi, da če bi hotel izpisati vse članke ali izdelke iz večjega števila gnezdenih kategorij, da bi se ti ta funkcija obesla oz. šla v timeout ?

Pa glede "default nesting level" ... to mi še vedno ni jasno kaj je ???? funkcija lahko gre v timeout če deluje preveč časa neglede in v tem času se lahko izvede 10x, 100x ali 1000x ..

Poženi tole kodo pa boš videl, o kakšni napaki govorim (Fatal error: Maximum function nesting level of '100' reached, aborting!)....

function count100($n) {
            static $n = 1;
            if ($n <= 100) {
                echo $n . '<br />';
                $n++;
                count100($n);
            }
        }

        count100(1);

V php.ini bi bilo potrebno povečati vrednost za xdebug.maxnestinglevel, če se ne motim.

Drugače pa moja koda generira na primer spodnje gnezdenje.

(podatki so iz večdimenzijskega polja, ki je generiran tako, da ima posamezna kategorija zapis $kategorija[$parent_id][$id] - na podlagi tega polja se potem z recursive ustvari seznam na zgornji sliki)

theuros:

thai:
Ni nujno, da ima nek meni 100 nivojev, vsaj pri moji skripti ne, če imaš 50 kategorij in ima vsak podkategorijo, se recursive kliče že 50x, ker mora za vsak podmeni pač kreirat nov meni. Sem pa omenil, da bodo rešitev uporabljali uporabniki in pri njih nikoli ne veš. Evo ti primer ene naključne strani... http://cult-trgovina.si/si/. Če imajo to rešeno z recursive, se ta kliče več kot 100x in php bi v tem primeru izpisal error (če bi ostala "default Maximum function nesting level of 100"). Tko da tale "halo?" lahko postane realnost :P

Očitno ti gradiš nek menu iz kategorij ki jih imaš .. ko se kreira prvi nivo greš za vsako kategorijo pogledat če ima podkategorijo in prikažeš še te .. in tako v nedogled v globino kolikor jih obstaja.

Kategorij ne sme biti toliko da bi se ti funkcija obesla .... pa če tudi .. še vedno lahko postopoma zlagaš meni in ne vsega naenkrat, ... pa tudi vse skupaj vržeš v cache tako da se ne izvede ob vsakem requestu ..

Vseh kategorij nima smisla imet na enkrat odprtih, tako da prikažeš samo aktivne in na klik izdeveš kak ajax da ti pokaže še podkategorije.

Si si pogleda meni na tej strani ? http://cult-trgovina.si/si/ Ne pride tu v poštev ajax, keširanje pa lahko uredim šele potem, ko je meni že zgeneriran.