Izgradnja stabla kategorija u PHP-u pomoću rekurzije. Drveće

Sljedeći zadatak je napraviti kategorije beskonačnog ugniježđenja koristeći PHP. Nakon surfanja po nekoliko stranica, pronašao sam mnoga rješenja, ali nisu sva dostupna mom razumijevanju, jer... Nivo programiranja tamo je viši od mog. Stoga sam pronašao najjednostavnije, možda ne najelegantnije, ali radno rješenje.

Prvo da vidimo šta imam u bazi podataka

  • id - identifikator naše kategorije
  • kategorija — naziv kategorije
  • category_id — identifikator nadređene kategorije. Mogli biste to nazvati parent_id, ali to mi je poznatije
  • lvl — nivo ugniježđenja kategorije. Potrebno za formiranje
  • Sve što se zataškava ne koristi vam, jer... Tamo ima informacija koje su meni lično neophodne, a da vas ne bih obmanuo, obrisao sam ove nepotrebne informacije.

Prikaz kategorija u "; ?>

Nema se tu šta puno reći, ako imate pitanja pišite u komentarima, a za one kojima nije baš svejedno šta ovdje piše, predlažem da odmah pogledate rezultat

Ako ne razumijete, onda nam je potrebno samo lvl polje u bazi podataka da bismo znali koliko "-" staviti ispred naziva kategorija. Naravno, postoji sofisticiranija metoda bez lvl-a, ali u ovom trenutku ovo je jedino rješenje koje imam. Čim se stvari promijene, ažurirat ću članak.

Prikaz kategorija u

Ali evo još jednog rješenja za vas, kada ga trebate prikazati ne u formi, već na listi.

"; while($rows = mysql_fetch_assoc($res))( $out .= "

  • ".$rows["kategorija"]."
  • "; foo($rows["id"]); ) $out .= ""; return $out; ) echo foo(0); ?>

    Ovdje nam više ne treba lvl, tako da ima manje koda. A ispod je rezultat

    28. maja , 2016

    Prilikom razvoja web aplikacija često se susrećemo s potrebom da podatke predstavimo u obliku stabla. Prilikom kreiranja iste online trgovine, linearna struktura kategorija proizvoda prikladna je samo za male projekte. Najčešće želite da budete u mogućnosti da ugnijezdite kategorije jedna u drugu. U drugim slučajevima, na primjer, ako kreirate upravitelj datoteka, još je teže bez kategorija.
    U ovom članku ću vam reći kako lako možete kreirati lijepo stablo podataka na vašoj web stranici, počevši od kreiranja tablice u mysql-u do prikazivanja stabla u pretraživaču. Koristićemo jstree biblioteku na klijentu i sami ćemo napisati jednostavan serverski kod.

    Šta ćemo učiniti i šta ćemo dobiti kao rezultat?

    Kao primjer, razmotrimo više puta spominjanu internet trgovinu i kreiramo stablo kategorija proizvoda za nju. Tradicionalno ćemo trgovati računarskom opremom. Prvo ćemo kreirati tabelu kategorija u mysql-u, zatim ćemo nacrtati oznake za stranicu kataloga, napisati js kod i, na kraju, php skriptu koja ulazi u bazu podataka i šalje kategorije klijentu u traženom formatu. I odmah link ka

    Kreirajte tabelu kategorija

    Da bismo kreirali proizvoljno razgranatu strukturu kategorija, potrebna nam je samo jedna tabela. Nazovimo ga kategorijama i napravimo 4 polja u njemu: id, kategorija, parent_id i broj. id će biti primarni ključ i auto-inkrement, kategorija je naziv kategorije, parent_id je id nadređene kategorije, broj je serijski broj kategorije u nadređenoj.

    Dozvolite mi da objasnim: na primjer, imamo 3 kategorije proizvoda, matična su laptopovi, a sadrži još 2 - Acer i Lenovo. U tabeli će to izgledati ovako:
    id, kategorija, roditelj_id, broj
    1, Laptopovi, 0, 1
    2, Acer, 1, 1
    3, Lenovo, 1, 2
    Hajde da se dogovorimo da će osnovne kategorije imati parent_id = 0. Brojčano polje je potrebno za organizovanje prikaza kategorija po željenom redosledu; ne garantujemo da će Acer uvek biti na prvom mestu, tako da morate biti u mogućnosti da promenite red prikaza. Svaka potkategorija ima svoju numeraciju, počevši od 1.

    Da biste bolje vidjeli kako je hijerarhija izgrađena, kreirajte tabelu u mysql-u i popunite je testnim podacima. Ispod je sql kod za oba. Kao i obično, bazu podataka ćemo zvati webdevkin.

    Struktura tabele kategorija

    koristite webdevkin; kreirajte kategorije tablice (id int(10) nepotpisan nije null auto_increment, kategorija varchar(255) nije null, parent_id int(10) nepotpisan nije null, broj int(11) nepotpisan nije null, primarni ključ (id)) engine = innodb auto_increment = 18 avg_row_length = 963 skup znakova utf8 collate utf8_general_ci;

    Test podaci

    koristite webdevkin; NAMENA SETOVA "utf8"; UMETNI U kategorije(`id`, `kategorija`, `parent_id`, `broj`) VRIJEDNOSTI (1, "Laptop", 0, 1), (2, "Acer", 1, 1), (3, "Lenovo ", 1, 2), (4, "Apple", 1, 3), (5, "Macbook Air", 4, 1), (6, "Macbook Pro", 4, 2), (7, "Sony Vaio", 1, 4), (8, "Pametni telefoni", 0, 2), (9, "iPhone", 8, 1), (10, "Samsung", 8, 2), (11, "LG" , 8, 3), (12, "Vertu", 8, 4), (13, "Komponente", 0, 3), (14, "Procesori", 13, 1), (15, "Memorija", 13 , 2), (16, "Video kartice", 13, 3), (17, "Tvrdi diskovi", 13, 4);

    Sada možete pogledati tabelu kategorija u uobičajenom phpMyAdmin-e ili dbForgeStudio i nastaviti sa kreiranjem naše mini-aplikacije.

    Struktura projekta

    U korenu projekta imaćemo index.html i 4 jednostavna foldera: img, css, js i php. Slika sadrži jednu sliku loading.gif. Biće prikazan posetiocima sajta dok se stablo kategorija učitava sa servera. Css folder sadrži datoteku main.css sa stilovima za našu stranicu i jstree folder, koji sadrži stilove i slike za jstree biblioteku.

    Za stara vremena, podijelit ćemo js folder na vendor i module. Prvi folder će sadržavati jquery i jstree biblioteke. Dozvolite mi da pojasnim - jquery je potreban ne samo za nas, već i kao zavisnost za jstree. U folderu moduli, jedina datoteka je main.js - glavna js skripta aplikacije. Poslat ćemo index.php u php folder, koji će obaviti sav posao na serveru.

    Ovaj put je zgodnije prvo razgovarati o serverskoj strani, a zatim prijeći na stranu klijenta. Stoga, pogledajmo kako izvući podatke iz tabele kategorija u traženom formatu - datoteci php/index.php

    Serverski kod - index.php

    Šta treba da radimo?

    • 1. Povežite se na bazu podataka
    • 2. Izvucite listu kategorija
    • 3. Pošaljite informacije pretraživaču

    Lista je jednostavna i ne bi trebalo biti problema sa implementacijom. Na početku fajla ćemo deklarisati potrebne konstante za povezivanje sa bazom podataka.

    // Deklarirati potrebne konstante define("DB_HOST", "localhost"); define("DB_USER", "korisnik"); define("DB_PASSWORD", "lozinka"); define("DB_NAME", "webdevkin");

    Zatim pišemo funkciju za povezivanje sa bazom podataka, koristeći mysqli.

    // Povezivanje sa funkcijom baze podataka connectDB() ( $errorMessage = "Ne mogu se povezati sa serverom baze podataka"; $conn = novi mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); ako (!$conn) izbaci novi izuzetak($ errorMessage ); else ( $query = $conn->query("set names utf8"); if (!$query) izbaci novi izuzetak($errorMessage); inače vrati $conn; ) )

    Zatim moramo izvući listu kategorija iz tabele. Ovdje moramo malo preduhitriti. Biblioteka jstree prihvata json kao ulaz. Prihvatljivi formati opisani su na web stranici biblioteke jstree.com. Mi ćemo uzeti onaj koji nam najviše odgovara i odmah ćemo poslati pripremljene podatke sa servera. Ovaj format izgleda ovako:

    [ ( "id" : "ajson1", "parent" : "#", "text" : "Jednostavan korijenski čvor" ), ( "id" : "ajson2", "parent" : "#", "text" : "Root node 2" ), ( "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" ), ( "id" : "ajson4", "parent" : "ajson2" , "tekst" : "Dijete 2" ), ]

    Primjer je preuzet iz dokumentacije, ali radi pogodnosti jednostavno ćemo koristiti id iz naše baze podataka kao id - broj bez prefiksa ajson. Prijeđimo na funkciju dobivanja kategorija iz tablice baze podataka

    // Dohvaćanje kategorija iz funkcije baze podataka getCategories($db) ( $query = " SELECT id KAO `id`, IF (parent_id = 0, "#", parent_id) KAO `parent`, kategorija kao `tekst` IZ kategorija ORDER BY `roditelj`, `broj` "; $data = $db->query($query); $categories = array(); while ($row = $data->fetch_assoc()) ( array_push($categories, array ( "id" => $row["id"], "parent" => $row["parent"], "text" => $row["text"])); ) vrati $kategorije; )

    Ovdje pokrećemo regularni upit za odabir na tabeli kategorija, izvlačimo 3 obavezna polja i istovremeno ih lagano transformišemo u traženi format. Mi prosljeđujemo id bez promjena, vraćamo parent_id kao roditelj, a za osnovne kategorije vraćamo #. I polje kategorije će biti proslijeđeno kao tekst. Podaci su primljeni, ostaje nam samo da ih stavimo u niz, koji ćemo konvertovati u json i poslati u pretraživač. Ovo je vidljivo u glavnoj niti skripte

    Pokušajte ( // Povežite se sa bazom podataka $conn = connectDB(); // Dobijte podatke iz niza GET $action = $_GET["action"]; switch ($action) ( case "get_categories": $result = getCategories( $ conn); break; default: $result = "nepoznata akcija"; break; ) // Vraća uspješan odgovor klijentu echo json_encode(array("code" => "uspjeh", "rezultat" => $rezult) ); ) catch (Izuzetak $e) ( // Vraća odgovor na grešku klijentu echo json_encode(array("code" => "error", "message" => $e->getMessage())); )

    Na šta treba obratiti pažnju. U našem konkretnom slučaju, prosljeđivanje parametra get u akciju izgleda nepotrebno, ali to je sve dok datoteka index.php služi samo jednom zadatku - da vrati listu kategorija. Uskoro će biti objavljen članak sa razvojem funkcionalnosti stabla, posebno implementacijom drag-and-drop na klijentu i ažuriranjem odgovarajućih podataka na serveru. U njemu ćemo vidjeti da je prosljeđivanje get parametra kao indikacije potrebne akcije prilično zgodna tema.

    I o odgovoru klijentu. Polje koda uvijek pokazuje status zahtjeva - uspjeh ili greška. Ako je uspješno, niz kategorija se vraća u polje rezultata; ako ima problema, poruka o grešci se šalje u polje poruke.

    To je to sa serverskim dijelom naše aplikacije, prijeđimo na klijenta.

    Oznaka za našu stranicu kataloga je index.html

    Ako ste već pogledali demo aplikacije, vidjet ćete da je markiranje izuzetno jednostavno. Postoje 2 glavna kontejnera: lijevo - za stablo kategorija, desno - rezervirano mjesto za listu proizvoda. Glava će sadržavati sljedeći kod:

    Webdevkin. Stablo kategorija u javascript, php i mysql

    Lista proizvoda

    I dodajte neke oznake u main.css

    Tijelo (familija fontova: Ubuntu; veličina fonta: 16px; težina fonta: 400; ) .container (pozicija: relativna; širina: 960px; margina: 0 auto; ) .kolona (prikaz: inline-block; vertikalno-align : vrh; ) .kategorije ( širina: 30%; )

    Završili smo sa html/css-om i sada pređimo na najzanimljiviji dio - javasctipt kod za kreiranje stabla. Ovdje ćemo sastaviti sve planirane funkcionalnosti.

    main.js - inicijalizacija aplikacije

    Ako ste pročitali prethodne članke, na primjer, o kreiranju korpe za internet prodavnicu na prednjoj strani ili o ugrađenim widgetima pomoću izvornog javascripta, možda ćete se sjetiti da je moja shema js koda približno ista za sve slučajeve.

    Primijenimo to i ovdje: kreirajte js modul na osnovu zatvaranja, keširajte potrebne elemente doma, napišite nekoliko privatnih metoda i jednu javnu - metodu inicijalizacije aplikacije.

    Okvir modula

    "koristi strogo"; // Aplikacijski modul var app = (function($) ( // Inicijaliziraj potrebne varijable var ajaxUrl = "/php", ui = ( $categories: $("#categories"), $goods: $("#goods") ) ); // Inicijalizacija stabla kategorija pomoću funkcije jstree _initTree(data) ( // ... ) // Učitavanje kategorija iz funkcije servera _loadData() ( // ... ) // Inicijalizacija aplikacijske funkcije init() ( _loadData( ); ) // Izvoz izvan return ( init: init ) ))(jQuery); jQuery(document).ready(app.init);

    Kao što možete vidjeti u posljednjem redu, nakon učitavanja dokumenta, pozivamo metodu app.init(), koja zauzvrat učitava podatke sa servera i prosljeđuje ih metodi kreiranja stabla. U ajaxUrl pišemo adresu naše serverske skripte; dva elementa dom će biti keširana u ui objektu.

    Podatke primamo sa servera - metodom _loadData().

    // Učitavanje kategorija iz funkcije servera _loadData() ( var params = ( akcija: "get_categories" ); $.ajax(( url: ajaxUrl, metoda: "GET", podaci: params, dataType: "json", uspjeh: function (resp) ( // Inicijaliziranje stabla kategorija if (resp.code === "uspjeh") ( _initTree(resp.result); ) else ( console.error("Greška pri primanju podataka sa servera: ", resp. poruka); ) ), greška: function(error) ( console.error("Greška: ", greška); ) )); )

    Ovdje pišemo najčešći Ajax zahtjev u serversku skriptu, primamo podatke sa kategorijama i, ako je uspješan, prosljeđujemo ih funkciji inicijalizacije stabla _initTree(). Sjećamo se da primamo podatke sa servera u json formatu, pa ćemo odmah naznačiti dataType: "json". I potrebne informacije će doći u polje rezultata, tako da tačno resp.result prosljeđujemo _initTree. Možete rukovati greškama na bilo koji način; na primjer, jednostavno ćemo ih baciti u konzolu.

    Izgradnja stabla u funkciji _initTree, koristeći jstree

    // Inicijaliziraj stablo kategorija koristeći jstree funkciju _initTree(data) ( ui.$categories.jstree(( core: ( check_callback: true, multiple: false, data: data ), plugins: ["dnd"] )).bind( "changed.jstree", funkcija (e, podaci) ( var kategorija = data.node.text; ui.$goods.html("Proizvodi iz kategorije " + kategorija); console.log("podaci čvora: ", podaci) ; )); )

    I to je sve što vam treba! Vizualno, najsloženiji dio aplikacije izgleda nevjerovatno jednostavno. Vi samo trebate primijeniti jstree metodu sa nekim parametrima na određeni dom element. U našem slučaju prosljeđujemo same podatke u polje podataka, multiple: false označava da nam nije potreban višestruki odabir, a check_callback: true označava da želimo učiniti nešto drugo nakon promjene stabla.

    U polju dodataka navodimo željene buns u nizu. Fokusirajmo se na dnd - povuci i ispusti - dodajmo mogućnost promjene strukture stabla pomoću miša. Ovo je vrlo zgodna stvar, ali još nije funkcionalna. Možete se igrati sa stablom u pretraživaču koliko god želite, ali nakon osvježavanja stranice vidjet ćemo staru strukturu direktorija. Ovo ima smisla jer se podaci uzimaju sa servera i nismo napisali nikakav kod za ažuriranje mysql-a na klijentske događaje. Jedan od sljedećih članaka će biti posvećen tome, ali za sada ćemo se poigrati pomicanjem kategorija pomoću miša u pretraživaču.

    I konačno, koristeći metodu vezivanja, povezujemo događaj promjene u stablu s nekom korisnom akcijom. U našem primjeru jednostavno ćemo prikazati natpis s nazivom kategorije, ali u stvarnoj aplikaciji vrijedilo bi povući listu proizvoda sa servera. Odakle dolazi kategorija = data.node.text? Otvorite konzolu vašeg pretraživača i pogledajte koji su nam još podaci o odabranom čvoru dostupni.

    Ukupno

    U ovom članku nismo napravili potpuni katalog za vođenje online trgovine - to nije bila ideja. Želeo sam da se fokusiram na to kako da izgradim tako korisnu strukturu kao što je drvo što je jednostavnije moguće od početka do kraja. Neke tačke su namerno izostavljene, a to je bliži rad sa samim stablom i sinhronizacija radnji klijenta sa serverom, kao i pravljenje liste proizvoda kada kliknete na kategoriju. Za prvu opciju ću objaviti poseban članak.

    AŽURIRANJE: Objavio sam članak koji pokazuje kako mišem premjestiti pojedinačne elemente stabla, koristeći drag-and-drop metod, i sinkronizirati te podatke sa serverom. Malo koda na klijentu i serveru - i voila! Link je ispod na broju 4.

    Nijedna web stranica nije potpuna bez navigacije ili, kako je još nazivaju, „menija web mjesta“. Dakle, meni stranice može biti na jednom nivou ili na više nivoa u obliku stabla. Ako nema posebnih poteškoća u smislu implementacije s menijem na jednom nivou, onda kada kreirate meni na više nivoa, morate pažljivo razmisliti.

    Najvažnija stvar u ovom zadatku je dizajn baze podataka za naš višeslojni meni. Kreirajmo tabelu kategorija sa tri polja id, naslov, roditelj gdje:

    • ID- identifikator
    • Naslov- Ime menija
    • Roditelj- Zadana kategorija roditelj 0

    Polje je odgovorno za grananje menija Roditelj Ako Roditelj = 0, onda je ova kategorija nadređena kategorija. Da biste dodali potomke u kategoriju roditelja, potrebno je da navedete u roditeljskom polju ID pravog roditelja. Na primjer:

    Tabele sa kategorijama

    Kao što se može vidjeti iz tabele, kategorija roditelja Automobili postoje dva potomka - ovo je Mazda I Honda povezane po oblastima Roditelj. I kategorija Motocikli dva potomka su Kawasaki I Harley. Istovremeno, kategorija Čamci nema potomaka. Nadam se da razumijete kako povezati kategorije.

    Zatim prelazimo sa riječi na praksu. Kreirajmo tabelu kategorija.

    KREIRAJ TABELU AKO NE POSTOJI `kategorije` (`id` int(10) nepotpisan NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `roditelj` int(10) nepotpisan NOT NULL, PRIMARNI KLJUČ (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ; -- -- Dump podataka iz tabele `kategorije` -- UMETNI U `kategorije` (`id`, `naslov`, `roditelj`) VRIJEDNOSTI (1, "Automobili", 0), (2, "Motocikli", 0 ) , (3, "Mazda", 1), (4, "Honda", 1), (5, "Kawasaki", 2), (6, "Harley", 2), (7, "Mazda 3", 3 ), (8, "Mazda 6", 3), (9, "Sedan", 7), (10, "Hatchback", 7), (11, "Čamci", 0), (12, "Liftback" , 8), (13, "Crosover", 8), (14, "Bijeli", 13), (15, "Crveni", 13), (16, "Crni", 13), (17, "Zeleni") , 13), (18, "Mazda CX", 3), (19, "Mazda MX", 3);

    Algoritam rada se sastoji od sljedećeg:

    Kreirajte vezu sa bazom podataka

    query("SET NAMES "utf8""); /* * Ovo je "zvanični" objektno orijentisan način da se ovo uradi * međutim $connect_error nije funkcionisao sve do PHP verzija 5.2.9 i 5.3.0. */ if ($mysqli->connect_error) ( die("Greška veze (" . $mysqli->connect_errno . ") " . $mysqli->connect_error); ) /* * Ako trebate biti sigurni u kompatibilnost sa verzijama prije 5.2 .9, * bolje je koristiti ovaj kod */ if (mysqli_connect_error()) ( die("Greška veze (" . mysqli_connect_errno() . ") " . mysqli_connect_error()); )

    Pisanje funkcije za dobijanje podataka iz tabele Kategorije

    //Nabavite niz našeg menija iz baze podataka kao funkciju niza getCat($mysqli)( $sql = "SELECT * FROM `categories`"; $res = $mysqli->query($sql); //Kreirajte niz gdje je ključ niza ID menija $cat = array(); while($row = $res->fetch_assoc())( $cat[$row["id"]] = $row; ) return $ mačka;)

    Dobijamo niz poput ovoga, gdje je ključ niza ID kategorije.

    Funkcija izrade od punog drveta od Tommy Lacroixa

    //Funkcija za izgradnju stabla iz niza iz Tommy Lacroix funkcije getTree($dataset) ( $tree = array(); foreach ($dataset kao $id => &$node) ( //Ako nema priloga ako ( !$node[" parent"])( $tree[$id] = &$node; )else( //Ako postoje djeca, onda ponovite niz $dataset[$node["parent"]]["childs "][$id] = &$ čvor; ) ) vrati $stablo; )

    Dobijamo niz u obliku stabla

    Cijela skripta

    query("SET NAMES "utf8""); /* * Ovo je "zvanični" objektno orijentisan način da se ovo uradi * međutim $connect_error nije funkcionisao sve do PHP verzija 5.2.9 i 5.3.0. */ if ($mysqli->connect_error) ( die("Greška veze (" . $mysqli->connect_errno . ") " . $mysqli->connect_error); ) /* * Ako trebate biti sigurni u kompatibilnost sa verzijama prije 5.2 .9, * bolje je koristiti ovaj kod */ if (mysqli_connect_error()) ( die("Greška veze (" . mysqli_connect_errno() . ") " . mysqli_connect_error()); ) //Nabavite niz našeg menija iz baze podataka kao funkcija niza getCat($mysqli)( $sql = "SELECT * FROM `categories`"; $res = $mysqli->query($sql); //Kreiraj niz gdje je ključ niza je ID menija $cat = array(); while ($row = $res->fetch_assoc())( $cat[$row["id"]] = $row; ) return $cat; ) //Funkcija za pravljenje stabla iz niza iz Tommy Lacroix funkcije getTree($dataset) ( $tree = array(); foreach ($dataset kao $id => &$node) ( //Ako nema priloga if (!$node[ "parent"])( $tree[$id] = &$node; )else( //Ako postoje potomci, onda prođite kroz niz $dataset[$node["parent"]]["childs"][$ id] = &$node; ) ) return $tree; ) //Nabavite pripremljeni niz sa podacima $cat = getCat($mysqli); //Kreirajte meni stabla $tree = getTree($cat); //Šablon za prikaz menija u obliku funkcije stabla tplMenu($category)( $menu = "
  • ". $category["title"].""; if(isset($category["childs"]))( $menu .= "
      ". showCat($category["childs"]) ."
    "; ) $menu .="
  • "; return $menu; ) /** * Rekurzivno pročitajte naš šablon **/ funkcija showCat($data)( $string = ""; foreach($data kao $item)( $string .= tplMenu($item); ) return $string; ) //Nabavite HTML oznaku $cat_menu = showCat($tree); //Prikaži eho "
      ".$cat_menu."
    "; ?>

    Rezultat rada

    Višeslojni meni u PHP + MySQL za admin panel

    Ako želite da koristite ovaj meni u admin panelu vaše stranice, onda morate prepisati nekoliko funkcija tplMenu(), showCat().

    ".$category["title"].""; )else( $menu = " "; ) if(isset($category["childs"]))( $i = 1; for($j = 0; $j< $i; $j++){ $str .= "→"; } $i++; $menu .= showCat($category["childs"], $str); } return $menu; } /** * Рекурсивно считываем наш шаблон **/ function showCat($data, $str){ $string = ""; $str = $str; foreach($data as $item){ $string .= tplMenu($item, $str); } return $string; } //Получаем HTML разметку $cat_menu = showCat($tree, ""); //Выводим на экран echo ""; ?>

    Rezultat rada

    Odaberite Automobili → Mazda →→ Mazda 3 →→→ Sedan →→→ Hatchback →→ Mazda 6 →→→ Liftback →→→ Crossover →→→→ Bijela →→→→ Crvena →→→ Crna →→→→ Zelena →→ Mazda CX →→ Mazda MX → Honda motocikli → Kawasaki → Harley Boats

    Danas ću vam reći kako MySQL kreirati hijerarhijsko stablo.

    Takva stabla se koriste pri izradi kategorija dinamičke stranice, na primjer, u online trgovini ili kada se prikazuju komentari na objavu.

    Uglavnom, grade se gdje god je to moguće. Glavna stvar je pravilno ga izgraditi i primijeniti.

    Najvažnija stvar pri izgradnji hijerarhijskog stabla je ispravna struktura baze podataka! Na primjer, razmotrite strukturu baze podataka u kojoj se pohranjuju kategorije lokacija. Za jednostavan primjer, tabela će imati 3 polja:

    1. id- ključ kategorije
    2. parent_id— id nadređene kategorije
    3. ime– naziv sekcije

    Kreirajmo tabelu pokretanjem SQL upita u PHPMyAdmin:

    CREATE TABLE `kategorije` (`id` INT NOT NULL AUTO_INCREMENT, `parent_id` INT NOT NULL, `name` VARCHAR(50) NOT NULL, PRIMARY KEY (`id`));

    Sada treba da ispunimo našu tabelu zapisima. Kao rezultat, trebali biste dobiti tabelu otprilike ovako:

    Možete popuniti probnu tabelu sa sljedećim upitom:

    UMETNI U `kategorije` (`id`, `parent_id`, `name`) VRIJEDNOSTI (1, 0, "Odjeljak 1"), (2, 0, "Odjeljak 2"), (3, 0, "Odjeljak 3") ), (4, 1, "Odjeljak 1.1"), (5, 1, "Odjeljak 1.2"), (6, 4, "Odjeljak 1.1.1"), (7, 2, "Odjeljak 2.1"), (8 , 2, "Odjeljak 2.2"), (9, 3, "Odjeljak 3.1");

    A sada pažnja! Zatim, logično, morate napraviti selekcije iz baze podataka u petlji kako biste odabrali svaku kategoriju i njenu podkategoriju. ALI! U redu je ako u bazi ima nekoliko kategorija, što takođe u principu nije tačno. Šta ako je stranica online trgovina i ima stotinu kategorija i isto toliko podkategorija? Onda nevolja! Nepoznati broj upita bazi podataka će dovesti do usporavanja stranice ili potpunog pada mysql servera.

    Možete koristiti samo jedan upit baze podataka da odaberete sve kategorije i njihove potkategorije.

    Napravimo zahtjev i stvorimo pogodan niz za dalji rad.

    //Odabir podataka iz baze podataka $result=mysql_query("SELECT * FROM category"); //Ako postoje zapisi u bazi podataka, formiramo niz if (mysql_num_rows($result) > 0)( $cats = array(); //U petlji formiramo niz sekcija, ključ će biti id roditeljske kategorije, kao i niz sekcija, ključ će biti id kategorije while($cat = mysql_fetch_assoc($result))( $cats_ID[$cat["id"]] = $cat; $cats[$ cat["parent_id"]][$cat["id"]] = $cat; ) )

    Odabir svih podataka iz tabele kategorije i formiraju asocijativni niz $cats, ključ će biti id nadređenih kategorija.

    Sada ćemo napraviti drvo. Za konstrukciju ćemo koristiti rekurzivna funkcija.

    Hijerarhijsko stablo će imati sljedeću strukturu:

    • Odjeljak 1
      • Odjeljak 1.1
        • Odjeljak 1.1.1
      • Odjeljak 1.2
    • Odjeljak 2
      • Odjeljak 1.1
      • Odjeljak 1.2
    • Odjeljak 3
      • Odjeljak 3.1

    Kreirajmo rekurzivnu funkciju build_tree() . To će izgraditi naše hijerarhijsko stablo apsolutno bilo kojeg gniježđenja.

    Funkcija build_tree($cats,$parent_id,$only_parent = false)( if(is_array($cats) i isset($cats[$parent_id]))( $tree = "

      "; if($only_parent==false)( foreach($cats[$parent_id] kao $cat)( $tree .= ""; ) )elseif(is_numeric($only_parent))( $cat = $cats[$parent_id ][$only_parent]; $tree .= "
    • ".$cat["name"]." #".$cat["id"]; $tree .= build_tree($cats,$cat["id"]); $tree .= "
    • "; ) $tree .="
    "; ) else vrati null; vrati $tree; )

    Funkcija uzima niz sekcija i id sekcije. U petlji prolazimo kroz potkategorije i ako imaju više sekcija, onda se funkcija ponovo pokreće sa novim parametrima (novi niz sekcija i id sekcije koju treba izgraditi). Tako nastaje drvo bilo kojeg gnijezda!

    Da bismo napravili stablo, pišemo u kodu:

    Echo build_tree($cats,0);

    Dakle, u dva koraka smo napravili hijerarhijsko stablo sekcija web stranice i nije važno koliko sekcija ima!

    UPD Ako vam je potrebno stablo kategorije obrnutim redoslijedom znajući id kategorije, onda trebate koristiti funkciju:

    Funkcija find_parent ($tmp, $cur_id)( if($tmp[$cur_id]["parent_id"]!=0)( return find_parent($tmp,$tmp[$cur_id]["parent_id"]); ) return ( int)$tmp[$cur_id]["id"]; )

    Ova funkcija uzima niz kategorija, čiji je ključ id kategorije i id kategorije iz koje trebate ići gore.

    Da biste napravili takvo stablo, pokrenite funkciju build_tree sa sljedećim parametrima:

    Echo build_tree($cats,0,find_parent($cats_ID,YOUR_CATEGORY_ID));

    Imate pitanja? Pitajte u komentarima

    Dohvaća elemente (termine) navedene taksonomije na osnovu navedenih parametara.

    Prije WP 4.5, prvi parametar za get_terms() bio je naziv taksonomije ili lista takvih imena:

    $terms = get_terms("post_tag", [ "hide_empty" => false, ]);

    Od WP 4.5, ime taksonomije mora biti navedeno u elementu niza taksonomije u parametru $args, a ne u drugom parametru, kao što je ranije bio slučaj:

    $terms = get_terms([ "taksonomija" => "post_tag", "hide_empty" => netačno, ]);

    Kompatibilnost unatrag radi (funkcija razumije zastarjeli poziv).

    Od verzije 4.6. pojavila se klasa meta upita WP_Term_Query(). A sada je funkcija get_terms() omot za ovu klasu.

    ✈ 1 put = 0,015166s = kočnica| 50000 puta = 33.29s = Tako sporo| PHP 7.1.11, WP 4.9.5

    Povratak

    Niz/WP_Error/string.

    • Niz WP_Term objekata - nakon uspješnog prijema.
    • array() (prazan niz) - ako pojmovi nisu pronađeni.
    • WP_Error - ako bilo koja od navedenih taksonomija ne postoji.
    • Broj pronađenih pojmova (kao string) - ako polja = count .

    Obrazac upotrebe

    $terms = get_terms(array("taxonomy" => array("post_tag", "my_tax"), // naziv taksonomije sa WP 4.5 "orderby" => "id", "order" => "ASC", "hide_empty " => true, "object_ids" => null, "include" => array(), "exclude" => array(), "exclude_tree" => array(), "number" => "", "polja" => "sve", "count" => lažno, "slug" => "", "roditelj" => "", "hijerarhijski" => tačno, "child_of" => 0, "dobi" => "" , // postavite sve da dobijete sve pojmove "name__like" => "", "pad_counts" => false, "offset" => "", "search" => "", "cache_domain" => "core", " name" => "", // str/arr ime polja da dobijete termin po njemu. C 4.2. "childless" => false, // true neće primiti (preskočiti) pojmove koji imaju podređene termine. C 4.2. " update_term_meta_cache " => true, // učitaj metapodatke u keš memoriju "meta_query" => "",)); foreach($terms kao $term)(print_r($term); )

    Upotreba

    get_terms($args, $deprecated); $args (niz/niz)

    Argumenti prema kojima će se dobiti rezultat.

    Među njima, traženi argument je $args["taksonomija"], koji specificira ime taksonomije ili nekoliko imena taksonomija u nizu.

    $deprecated (niz/niz) Prije verzije 4.5, ovaj argument je specificirao $args parametre, a prvi parametar $args specificirao je nazive taksonomija. Od verzije 4.5, imena taksonomija su navedena u argumentu $args["taxonomy"].
    Default: niz zadanih argumenata

    Argumenti parametara $args

    taksonomija (niz/niz) (obavezno) Naziv taksonomije za rad. Možete navesti više imena kao niz. Od WP 4.5, prije ovoga, nazivi taksonomije su specificirani u prvom parametru same funkcije. broj (broj) Maksimalan broj artikala koji će biti primljeni. Limit.
    Zadano: sve. object_ids (broj/niz)

    Ovdje navedite broj ili niz brojeva da biste dobili pojmove čije polje object_id u tabeli wp_term_relationships odgovara navedenim vrijednostima.

    Tipično, polje object_id sadrži ID-ove zapisa kojima je termin vezan.

    Uključi (niz/niz) ID-ovi termina koji će biti uključeni u odabir. Ako navedete ovaj parametar, mnogi drugi će postati beskorisni. Raščlanjen putem wp_parse_id_list() .
    Zadano: "" isključiti (niz/niz) ID-ovi uslova koje treba isključiti. Raščlanjen putem wp_parse_id_list() .
    Zadano: "" exclude_tree (niz/niz) ID nadređenih uslova koje treba isključiti. Cijela nit će biti isključena.
    Raščlanjen putem wp_parse_id_list() .
    Zadano: "" offset (broj) Gornja uvlaka u zahtjevu. Koliko prvih elemenata treba preskočiti. Morate navesti broj. Podrazumevano, bez uvlačenja. Poredak po (linija)

    Polje po kojem se sortiraju rezultati. Možda:

    • id ili term_id - po ID-u.
    • ime - po imenu. Default.
    • count - po count polju u termin_taxonomy - prema broju zapisa.
    • puž - alternativnim imenom.
    • opis - prema opisu.
    • termin_grupa - po grupi.
    • roditelj - prema roditelju polja.

    • uključiti - redoslijedom navedenim u parametru $include
    • slug__in - od verzije 4.9. Po redoslijedu navedenom u parametru $slug.
    • meta_value - po vrijednosti prilagođenog polja
    • meta_value_num - na osnovu vrijednosti prilagođenog polja, vrijednost će se tumačiti kao broj, a ne kao niz.
    • ključ "meta_query" - u parametru $meta_query možemo specificirati parametre upita po meta poljima, a također navesti ključ za određeni upit tamo. Ovaj ključ se može koristiti kao ključ za sortiranje prema odgovarajućem metapolju.
    • nema - ne sortiraj

    Zadano: "id"

    red (linija)

    Smjer sortiranja naveden u parametru "orderby":

    • ASC - redom, od najmanjeg do najvećeg (1, 2, 3; a, b, c);
    • DESC - obrnutim redoslijedom, od najvećeg prema najmanjem (3, 2, 1; c, b, a).

    Zadano: "ASC"

    Sakrij_prazno (logično) Da li sakriti pojmove koji nemaju unose. 1(true) - sakriti prazne, 0(false) - prikazati prazne.
    Podrazumevano: istina polja (linija)

    Koja polja vratiti u rezultirajući niz. Možda:

    • sve - Vrati niz objekata (svi podaci) - zadano;
    • ids - vraća niz brojeva;
    • imena - vraćaju niz stringova.
    • count - (3,2+) vraća broj pronađenih pojmova.
    • id=>parent - vraća niz gdje je ključ = ID pojma i vrijednost = ID roditeljskog pojma.
    • id=>slug - vraća niz, gdje je ključ = ID termina, a vrijednost = slug (ime za URL) termina.
    • id=>name - vraća niz, gdje je ključ = ID pojma, a vrijednost = ime (ime) pojma.

    Zadano: "sve"

    count (logično) true - vratiće broj pojmova. U ovom slučaju, parametar polja je poništen.
    false - vratit će niz objekata termina. ime (niz/niz) Ovdje navedite string ili niz stringova da biste dobili pojmove sa navedenim imenima.
    Zadano: "" puž (niz/niz) Ovdje navedite string ili niz stringova da biste dobili termine sa navedenim oznakama (slagovi).
    Zadano: "" hijerarhijski (logično)

    Treba li uključiti pojmove koji imaju neprazne podređene pojmove (koji imaju unose) u rezultat. One. Prazni termini će biti uključeni u niz ako njihovi podređeni termini imaju unose, čak i ako je argument "hide_empty" istinit.

    • istina - da, omogući;
    • false - ne, ne omogućavaj.

    Podrazumevano: istina

    Traži (linija) Pretražite po nazivu pojma i oznaci. Dobiva termine čija imena sadrže pojavljivanje niza koji je ovdje specificiran. One. zahtjev izgleda ovako: LIKE "%search_string%" .
    Zadano: "" name_like (linija) Prikaži pojmove koji imaju navedeni niz u svom naslovu. Traži po nizu.
    Zadano: "" description__like (linija) Prikaži pojmove koji imaju navedeni niz u opisu. Traži po nizu.
    Zadano: "" pad_counts (logično)

    Ako prođete true, onda će broj koji pokazuje broj postova u nadređenim kategorijama biti zbir njegovih postova i objava iz podređenih kategorija. Po defaultu se računaju samo vlastiti zapisi.

    pad_counts zavisi od parametra parent jer se brojanje zapisa dešava na nivou PHP-a i ako, na primer, navedete parent=0, tada će biti primljeni samo gornji termini i pad_counts neće moći pravilno da prebroje broj zapisa u dečiji termini. Da biste zaobišli ovo ograničenje, morate dobiti sve pojmove bez navođenja parent , a zatim ukloniti nepotrebne u PHP-u... Evo primjera takvog koda:

    $terms = get_terms(array("hide_empty" => 0, "orderby" => "name", "order" => "ASC", "taksonomija" => "kategorija", "pad_counts" => 1)); // ostavi samo pojmove sa parent=0 $terms = wp_list_filter($terms, array("parent"=>0));

    Podrazumevano: false

    dobiti (linija)

    Ako navedete "sve" tada će sljedeći parametri biti strogo onemogućeni: childless , child_of , hide_empty , hierarchical i pad_counts . “Hard” znači da će nadjačati trenutne postavke za ove parametre. “Onemogućeno” znači da će parametar biti postavljen na false ili 0.

    Obično se koristi za praktičnost kada trebate dobiti termine na niskom nivou, ne za izlaz, već za daljnji rad s njima, kako ne biste pratili vrijednosti navedenih parametara...

    // isječak koda if ("all" == $args["get"]) ( $args["childless"] = false; $args["child_of"] = 0; $args["hide_empty"] = 0; $args["hierarchical"] = netačno; $args["pad_counts"] = lažno; )

    Zadano: ""

    child_of (broj)

    ID roditeljskog termina. Navedite elemente taksonomije koji su potomci navedenog elementa. Dobit će se svi nivoi gniježđenja, cijelo stablo.

    Ako je navedeno više taksonomija, parametar će se zanemariti.
    Podrazumevano: 0

    Roditelj (broj)

    ID roditeljskog termina da biste dobili samo direktnu djecu.

    Dobit će se samo prvi nivo ugniježđenja, a ne cijelo stablo kao u parametru child_of. Ako navedete 0, termini najvišeg nivoa će biti prikazani.
    Zadano: ""

    Term_taxonomy_id (broj/niz) Ovdje navedite broj ili niz brojeva da biste dobili pojmove čije polje term_taxonomy_id odgovara navedenim vrijednostima.
    Zadano: "" cache_domain (linija)(3.2+) Omogućava vam da postavite jedinstveni ključ keša koji će se koristiti u get_terms() kada se koristi predmemorija objekata. Na primjer, ako koristite jedan od filtera get_terms() za izmjenu upita (npr. "terms_clausses"), postavljanje "cache_domain" na jedinstvenu vrijednost omogućit će vam da izbjegnete prepisivanje pohranjene keš memorije za iste upite.
    Zadano: "core" update_term_meta_cache (logično) true - učitaj keš metapodataka tako da se kasnije može brzo preuzeti. Keš memorija se učitava za primljene elemente.
    Podrazumevano: istina meta_query (niz) Upit za dohvat stavki na osnovu metapodataka. Pogledajte WP_Meta_Query. meta_key (linija) Dobiva pojmove koji imaju navedeno metapolje. Može se koristiti zajedno sa meta_value.
    Zadano: "" meta_value (linija) Dobija pojmove čija je vrijednost metapolja jednaka navedenoj vrijednosti. Uvijek se koristi zajedno sa meta_key.
    Zadano: "" suppress_filter (logično) Da li treba da potisnem filtere ili ne? Ako je postavljeno na true, filter get_terms jednostavno neće raditi za trenutni upit pojma.
    Zadano: false (filtri rade)

    Primjeri

    #1 Nabavite niz podataka o svim kategorijama na stranici

    Podaci u nizu će biti sortirani prema broju unosa (orderby=count) u svakoj kategoriji. Kategorije koje nemaju unose će i dalje biti uključene u niz (hide_empty=0).

    $myterms = get_terms("kategorija", "orderby=count&hide_empty=0");

    #2 Prikaži listu imena svih sekcija taksonomije "my_taxonomy":

    $terms = get_terms("moja_taksonomija"); if($terms && ! is_wp_error($terms))( echo "
      "; foreach($terms kao $term)( echo "
    • ". $term->name ."
    • "; ) echo "
    "; }

    U ovom primjeru, svaki $term iz foreach($terms as $term) petlje će sadržavati sljedeće informacije:

    => 162 => Zdravlje => zdravlje => 0 => 170 => moja_taksonomija => => 0 => 2

    #3 Prikaz kategorija kroz separator

    // dobijamo sve pojmove iz taksonomije my_term $args = array("hide_empty=0"); $terms = get_terms("my_term", $args); // prikupiti ih i ispisati ako (!empty($terms) && !is_wp_error($terms)) ( $count = count($terms); $i=0; $term_list = "

    "; foreach ($terms kao $term) ($i++; $term_list .= "name) . "">" . $term->name . ""; if ($count != $i) ( $term_list .= " · "; ) else ( $term_list .= "

    "; ) ) echo $term_list; ) /* završavamo sa kodom poput ovog: */

    Lista promjena

    Od verzije 2.3.0 Uvedeno.
    Od verzije 4.2.0 Uvedeni parametri "ime" i "bez djece".
    Od verzije 4.4.0 Uvedena je mogućnost prosljeđivanja "term_id" kao pseudonima "id" za parametar orderby. Uvedeni parametri "meta_query" i "update_term_meta_cache". Konvertirano za vraćanje liste WP_Term objekata.
    Od verzije 4.5.0 Promijenjen potpis funkcije tako da se niz $args može dati kao prvi parametar. Uvedeni parametri "meta_key" i "meta_value". Uvedena mogućnost redosleda rezultata prema metapodacima.
    Od verzije 4.8.0 Uveden parametar "suppress_filter".

    Kod dobiti uslove: wp-includes/taxonomy.php WP 5.2.3

    lažno,); /* * Naslijeđeni format argumenta ($taksonomija, $args) ima prednost. * * Otkrivamo naslijeđeni format argumenta provjerom da li je * (a) proslijeđen drugi neprazan parametar, ili * (b) prvi parametar ne dijeli ključeve sa zadanim nizom (tj., to je lista taksonomija) */ $taxonomies = ( niz) $args; $args = wp_parse_args($deprecated, $defaults); $args["taxonomy"] = $taxonomies; ) else ( $args = wp_parse_args($args, $defaults); if (isset ($args[ "taksonomija"]) && null !== $args["taksonomija"]) ( $args["taksonomija"] = (niz) $args["taksonomija"]; ) ) if (! prazno($ args["taxonomy" "])) ( foreach ($args["taxonomy"] kao $taksonomija) (if (! taxonomy_exists($taxonomy)) (vrati novu WP_Error("invalid_taxonomy", __("Nevažeća taksonomija.") ); ) ) ) // Nemojte prosljeđivati ​​suppress_filter u WP_Term_Query. $suppress_filter = $args["suppress_filter"]; unset($args["suppress_filter"]); $terms = $term_query->query($args); // Broj upita se ne filtriraju iz naslijeđenih razloga. if (! is_array($terms)) ( return $terms; ) if ($suppress_filter) ( return $terms; ) /** * Filtrira pronađene pojmove. * * @od 2.3.0 * @od 4.6.0 Dodan parametar `$term_query`. * * @param array $terms Pronađen je niz pojmova. * @param array $taxonomies Niz taksonomija. * @param array $args Niz get_terms() argumenata. * @param WP_Term_Query $term_query Objekt WP_Term_Query. */ return apply_filters("get_terms", $terms, $term_query->query_vars["taxonomy"], $term_query->query_vars, $term_query); )
    Slični članci

    2023 ap37.ru. Vrt. Dekorativno grmlje. Bolesti i štetočine.