itthon / Dolgozzon az interneten / Fa építése php adatbázisból. PHP kategóriák (Kategória fa). Array Tree Function, Tommy Lacroix

Fa építése php adatbázisból. PHP kategóriák (Kategória fa). Array Tree Function, Tommy Lacroix

Ma elmondom, hogyan hozhat létre hierarchikus fát a MySQL-ben.

Az ilyen fákat egy dinamikus webhely kategóriáinak felépítéséhez használják, például egy online áruházban, vagy amikor megjegyzéseket jelenítenek meg egy bejegyzéshez.

Általában ott építik, ahol csak lehetséges. A lényeg a helyes felépítés és alkalmazás.

A hierarchikus fa felépítésénél a legfontosabb a helyes adatbázis-struktúra! Vegyük például annak az adatbázisnak a szerkezetét, amelyben a webhely kategóriái vannak tárolva. Mert egyszerű példa, a táblázat 3 mezőt tartalmaz:

  • id - kategória kulcs
  • parent_id — szülőkategória azonosítója
  • név - szakasz neve
  • Hozzon létre egy táblázatot egy SQL lekérdezés végrehajtásával a PHPMyAdminban:

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

    Most meg kell töltenünk a táblázatunkat rekordokkal. Ennek eredményeként valami ehhez hasonló táblázatot kell kapnia:

    A teszttáblát a következő lekérdezéssel töltheti fel:

    INSERT INTO `categories` (`id`, `parent_id`, `name) ÉRTÉKEK (1, 0, "1. szakasz", (2, 0, "2. szakasz"), (3, 0, "3. szakasz") ), (4, 1, "1.1. szakasz"), (5, 1, "1.2. szakasz", (6, 4, "1.1.1. szakasz"), (7, 2, "2.1. szakasz"), (8 , 2, "2.2. szakasz"), (9, 3, "3.1. szakasz");

    És most figyelem! Továbbá logikailag az adatbázisból egy ciklusban kell kiválasztania az egyes kategóriákat és alkategóriáit. DE! Nos, ha több kategória is van az adatbázisban, ami szintén elvileg nem helyes. És ha az oldal egy webáruház, és száz kategóriája és ugyanannyi alkategóriája van? Akkor baj! Az adatbázisba irányuló ismeretlen számú lekérdezés lelassítja a webhelyet, vagy teljesen összeomlik a mysql szerver.

    Az összes kategória és azok alkategóriáinak kiválasztásához csak egy lekérdezést használhat az adatbázishoz.

    Tegyünk egy kérést, és alkossunk egy kényelmes tömböt a további munkához.

    //Adatok kiválasztása az adatbázisból $result=mysql_query("SELECT * FROM kategóriák"); //Ha vannak rekordok az adatbázisban, akkor tömböt képezünk if (mysql_num_rows($result) > 0)( $cats = array(); //A ciklusban szakaszokból álló tömböt alkotunk, a kulcs a a szülőkategória azonosítója, valamint a szakaszok tömbje, a kulcs a kategóriaazonosító lesz while($cat = mysql_fetch_assoc($result))( $cats_ID[$cat["id"]] = $cat; $cats[ $cat["parent_id"]][$cat["id"]] = $macska; ) )

    A kategóriák táblájából kiválasztunk minden adatot és egy asszociatív tömböt alkotunk $cats , a kulcs a szülőkategória azonosítója.

    Most fát építünk. A felépítéshez rekurzív függvényt fogunk használni.

    A hierarchikus fa szerkezete a következő lesz:

    • 1. szakasz
      • 1.1
        • 1.1.1
      • 1.2
    • 2. szakasz
      • 1.1
      • 1.2
    • 3. szakasz
      • 3.1

    Hozzunk létre egy rekurzív függvényt build_tree(). Ez fel fogja építeni a hierarchikus fájunkat, amely teljesen bármilyen fészkelőt tartalmaz.

    függvény build_tree($cats,$parent_id,$only_parent = false)( if(is_array($cats) and isset($cats[$parent_id]))( $tree = "

      "; if($only_parent==false)( foreach($cats[$parent_id] as $cat)( $tree .= ""; ) )elseif(is_numeric($only_parent))( $cat = $cats[$parent_id ][$only_parent]; $fa .= "
    • ".$cat["név"]." #".$cat["id"]; $fa .= build_tree($cats,$cat["id"]); $fa .= "
    • "; ) $fa .= "
    "; ) else return null; return $fa; )

    A függvény szakaszokból álló tömböt és szakaszazonosítót vesz fel. A ciklusban végigmegyünk az alkategóriákon, és ha több szakaszuk van, akkor a függvény új paraméterekkel (új szakaszok tömbje és az építendő szakasz azonosítója) újra lefut. Így keletkezik minden fészekfa!

    Fa építéséhez a kódba írjuk be:

    echo build_tree($cats,0);

    Tehát két lépésben létrehoztuk a webhelyszakaszok hierarchikus fát, és nem számít, hány szakasz van!

    UPD Ha kategóriafára van szüksége fordított sorrendben a kategóriaazonosító ismeretében a következő függvényt kell használnia:

    Függvény 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"]; )

    Ez a függvény egy sor kategóriát vesz fel, amelyek kulcsa a kategória azonosítója, és annak a kategóriának az azonosítója, ahonnan fel kell lépni.

    Egy ilyen fa felépítéséhez futtassa a build_tree függvényt a következő paraméterekkel:

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

    Kérdései vannak? Kérdezd meg a kommentekben

    Ma célunk a kategóriák hierarchikus struktúrájának kialakítása. Számunkra fontos, hogy kényelmes legyen a kategóriák tárolása, és könnyen megjeleníthető legyen ott, ahol szükségünk van rájuk.

    Néha az egyszerű bonyolultnak tűnik, ezért kirakok néhány kódrészletet, amelyek remélem hasznosak lesznek a php kategóriák fa formájában való megvalósításához.

    Tehát a szerkezetnek a kategóriaazonosítóból (id), a kategória nevéből (név) és természetesen a szülőkategória azonosítójából (parent_id) kell állnia. A MySQL-ben így néz ki:

    TÁBLÁZAT LÉTEZÉSE, HA NEM LÉTEZ `category` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `parent_id` int(11) NOT NULL, PRIMARY KEY (`id`)) ENGINE =InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;

    Minimális és érthető táblázatstruktúra a kategóriák tárolására.

    INSERT INTO `category` (`id`, `name`, `parent_id`) ÉRTÉKEK (1, "Telefonok és táblagépek", "0"), (2, "Autók", "0"), (3, "Samsung" ", "1"), (4, "Apple", "1"), (5, "LG", "1"), (6, "Ford", "2"), (7, "Lexus", "2"), (8, "BMW", "2"), (9, " Galaxy Tab 4", "3"), (10, "Galaxy S6", "3");

    Ahol parent_id=0, ennek a kategóriának nincs szülőkategóriája.

    Itt minden világos és egyszerű. Most pedig térjünk át a kategóriák felsorolására. De a lista helyes kimenetéhez először be kell szereznünk a php kategóriák teljes listáját, és csak ezután, rekurzió segítségével, létrehozzuk a fánkat. Következő funkció meg kell szerezni ezt a listát:

    Függvény get_cat() ( // lekérdezi az adatbázist $sql = "SELECT * FROM kategória"; $result = mysql_query($sql); if(!$result) ( return NULL; ) $arr_cat = array(); if( mysql_num_rows ($eredmény) != 0) ( //For($i = 0; $i< mysql_num_rows($result);$i++) { $row = mysql_fetch_array($result,MYSQL_ASSOC); //Формируем массив, где ключами являются адишники на родительские категории if(empty($arr_cat[$row["parent_id"]])) { $arr_cat[$row["parent_id"]] = array(); } $arr_cat[$row["parent_id"]] = $row; } //возвращаем массив return $arr_cat; } }

    //katalógustömb lekérése $eredmény = get_cat();

    Most egy rekurziós függvényre van szükségünk

    Függvény view_cat($arr,$parent_id = 0) ( //Rekurzió kilépési feltételei if(empty($arr[$parent_id])) ( return; ) echo "

      "; // végigpörgeti a tömböt, és megjeleníti a for($i = 0; $i< count($arr[$parent_id]);$i++) { echo "
    • " .$arr[$parent_id][$i]["name"].""; //rekurzió - ellenőrizze, hogy vannak-e gyermekkategóriák view_cat($arr,$arr[$parent_id][$i]["id" "] ); visszhang "
    • "; ) visszhang"
    "; }

    Most már csak a könyvtárat kell megjeleníteni a képernyőn a rekurzív funkció segítségével

    View_cat($eredmény);

    És általában ennyi. Így egy teljes kategóriafát kaphatunk végtelen alkategóriákkal.

    Így kezdésként leírom, mivel fogunk dolgozni, és mire lesz szükségünk.
    Rendszer: PHP 5 és újabb, mySQL 4 és újabb
    Segítő osztályok: dbsql.class.php (adatbázis osztály)
    Beágyazott kategóriaosztály : classTreeCategory.php (közvetlenül a fő osztály, annak felsorolása és magyarázata lent található.

    Hozzon létre egy táblázatot az adatbázisban a következő szerkezettel:

    Kód megtekintése MySQL

    Ez a táblázat tartalmazza az ID mezőt - a kategória sorozatszámát, podcat - értéke nulla az elsőrendű kategóriáknál vagy a szülőkategória azonosítója, név - a kategória neve.

    Példa az osztályra, amely a kategóriákat listaként jeleníti meg alkategóriákkal:

    Kód megtekintése PHP

    include("dbsql.class.php") ; include("classTreeCategory.php" ) ; $DB = new DB_Engine("mysql" , $settings [ "dbHost" ] , $settings [ "dbUser" ] , $settings [ "dbPass" ] , $settings [ "dbName" ] ) ; // csatlakozás az adatbázishoz, hozzáférési adatok megadásával $category = new TreeCategory ($DB ) ; // átadás a kategóriaosztálynak, az adatbázissal végzett munka objektumának $category -> table = "category" ; // táblázat neve az adatbázisban kategóriákkal $array = $category -> getCategory () ; // az adatbázisból az összes kategóriát többszintű tömbként lekérjük, a szükséges sorrendben rendezve és egymásba ágyazva $category -> outCategory ($tömb , "opció" ) ; // kategóriák kimenetének előkészítése (HTML kialakítása), tömb átadása kategóriákkal echo $category -> html ; // kategóriák megjelenítése HTML névként

    Ahogy a fenti példából is látható, minden rendkívül egyszerű, létrehozunk egy új $category objektumot, beállítjuk, hogy melyik adatbázistáblával dolgozunk: 'category', majd a táblázatból megkapjuk az összes olyan kategória listáját, amely már formázva van. tömböt, és hierarchikus sorrendben bontják, figyelembe véve az összes alkategóriát. majd a tömböt átadjuk az outCategory() metódusnak, ami egy kész HTML kódot generál nekünk, amit már csak a böngészőben kell megjeleníteni.

    Az outCategory() metódus, mint látjuk, két paraméterből @array és @string az első paraméterben egy tömböt vesz fel minden kategóriával, a másodikban pedig egy opciót vagy táblaértéket tartalmazó karakterláncot, ez az érték jelzi, hogy milyen típusú HTML kód elő kell állítani.
    opció értéke

    Kód megtekintése HTML

    -category1 --alcategory 1 ---alcategory 1 -category 2

    A megadott HTML kód beszúrása bármely űrlap kijelölő mezőjébe.

    A táblázat értéke a következő HTML-kódot generálja:

    Kód megtekintése HTML

    Ezt a HTML-kódot praktikusan beillesztheti egy táblázatba, amely megjeleníti az összes kategória-alkategóriánkat.

    Az osztály a következő metódusokkal is rendelkezik:
    deleteItem($id); - a beágyazott kategóriák ellenére eltávolít egy kategóriát
    delCategory($tömb, $id); — eltávolít egy kategóriát az összes beágyazott alkategóriával, $tömb — a $category->getCategory() metódussal készített tömb minden kategóriájával, $ személyi igazolvány száma törlendő kategória
    addItem(); - ezt a metódust meg kell hívni, ha kategóriát szeretne hozzáadni, miközben ez a módszer a POST módszerrel továbbított adatokból olvassa ki az értékeket, pl. a $_POST tömbből.
    $name=$this->PHP_slashes(csík_címkék($_POST['név'])); // kategória név
    $podcat=intval($_POST['podcat']); // A szülőkategória azonosítója, ha 0 van megadva, akkor a kategória a gyökérben lesz.
    updateItem() ; - hasonló az előző módszerhez, azzal a különbséggel, hogy ez a módszer frissíti a kategóriát, annak nevét és beágyazási szintjét.

    table="kategória"; // kérés a kategóriák listájának kiválasztásához, tábla neve * $category->outCategory($category->getCategory()); // kategóriakimenet előkészítése (kategóriák tömbjének lekérése) * echo $category->html; // kategóriák megjelenítése HTML névben * */ /** * A folyamatban lévő táblázat kiírása * * TÁBLÁZAT DROP TABLE IF EXISTS `kategória`; * CREATE TABLE `category` (* `id` int(11) NOT NULL auto_increment, * `podcat` int(11) NOT NULL, * `name` varchar(255) NOT NULL, * PRIMARY KEY (`id`), * KEY `id` (`id`) *) ENGINE=MyISAM DEFAULT CHARSET=utf8; * */ class TreeCategory ( /** * Adatbázis lekérdezési karakterlánc */ var $table; /** * Adatbázis felület */ var $DB; /** * Kategóriák tömbje beágyazott alkategóriákkal */ var $arrayCat; / ** * Automatikusan megszámolja a kategórianév előtti kötőjelek számát */ var $countPodcat megjelenítésekor; /** * HTML-kód az alkategóriákkal rendelkező kategóriák megjelenítéséhez */ var $html; /** * Szerezze be az adatbázissal való munkavégzéshez szükséges felületet és tedd be egy helyi változóba */ function __construct($DB) ( $this->DB=$DB; $this->component=$_GET["komponens"]; ) /** * Lekéri a kategóriák listáját, rendez és egy tömbbe helyezi beágyazott tömböket stb. * @return tömbkategória */ függvény getCategory () ( $all = $this->DB->getAll("SELECT * FROM `($this->table)` ORDER BY `id` ASC"); $útvonal = array(); if(count($all)>0) ( foreach($all mint $item): if($item["podcat"]==0)$sort[ $item[ "id"]]=$item; if($item["podcat"]>0) ( if(isset($path[$item["podcat"]])) ( $str="$sort" foreach( $path[$item["podcat"]] mint $pitem): $rep=$item["podcat"]; $str.="[$pitem]"; endforeach; $str.="[($item["podcat"])]"; $str.="[($item["id"])]"; $str.="=$elem;"; eval($str); foreach($path[$item["podcat"]] mint $pitem): $path[$item["id"]]=$pitem; endforeach; $elérési út[$item["id"]]=$item["podcat"]; ) else ( $sort[$item["podcat"]]["sub"][$item["id"]]=$item; $elérési út[$item["id"]]=$item["podcat" ]; ) ) endforeach; ) $this->arrayCat=$rendezés; return $this->arrayCat; ) /** * Kinyomtatja a kategóriákat, a kész HTML-t a $this->html-be helyezi * @param tömb Tömb kategóriákkal és beágyazott alkategóriákkal * @param string A generált HTML kód típusa a kimenetre, opció vagy táblázat */ függvény outCategory(& $arrayCat, $type="option", $idSel=0) ( foreach($arrayCat mint $sub) ( $this->countPodcat++; $this->outItem($sub, $type); if(!empty($) sub[" sub"]))$this->outCategory($sub["sub"], $type, $idSel); $this->countPodcat--; ) ) /** * Segítő módszer HTML kód elkészítéséhez * @param tömb Kategóriájú tömb * @param string A generált HTML kód típusa a kimenetre, opció vagy táblázat */ függvény outItem($sub, $type="option", $idSel=0) ( for($i=0;$ icountPodcat;$i++) ($ki. ="-"; ) if($idSel==$sub["id"])$se="kijelölve"; else $se=""; if($type=="opció")$this->html.=" ($out) ($sub["név"]) "; if($type=="table")$this->html.= ($out) ($sub["név"]) HTML; ) függvény delCategory(&$a_tree,&$id=0) ( foreach($a_tree mint $sub) ( if($sub["id"]$id and isset($sub["sub"]))$this- >delCategory($sub["al"],$id); if($sub["id"]==$id) ( $sql="DELETE FROM ($this->table) WHERE id = "$id" LIMIT 1"; $this->DB->execute($sql); if (isset($sub["sub"])) $this->delCategory_process($sub["sub"]); ) ) ) function delCategory_process (&$a_tree) ( foreach($a_tree mint $sub) ( $sql="DELETE FROM ($this->table) WHERE id = "($sub["id"])" LIMIT 1"; $this-> DB->execute($sql); if(isset($sub["sub"]))$this->delCategory_process($sub["sub"]); ) ) function updateItem() ( $name=$this- >PHP_slashes(csík_címkék($_POST["név"])); $podcat=intval($_POST["podcat"]); $id=intval($_POST["id"]); $sql="UPDATE `( $this->table)` SET `name` = "($név)",`podcat` = "($podcat)" WHERE `id`="($id)" LIMIT 1; "; $this->DB ->execute($sql); ) függvény addItem() ( $name=$this->PHP_slashes(strip_tags($_POST["név"])); $podcat=intval($_POST["podcat"]); $ id=intval($_POST["id"]); $sql="INSERT INTO `($this->table)` (`id`,`podcat`,`name`) ÉRTÉKEK ("", "$podcat" , "$név");"; $this->DB->execute($sql); ) függvény deleteItem($id) ( $id=intval($id); $sql="DELETE FROM `($this->table)` WHERE `id` = "($id)" LIMIT 1"; $DB- >execute($sql); header("Hely: ?component=($this->component)"); ) function PHP_slashes($string,$type="add") ( if ($type == "add") ( if (get_magic_quotes_gpc()) ( return $string; ) else ( if (function_exists("addslashes")) ( return addslashes($string); ) else ( return mysql_real_escape_string($string); ) ) ) else if ($type == "csík") ( return stripslashes($string); ) else ( die("hiba a PHP_slashesben (mixed,add | strip)"); ) ) )

    Az egész osztályt egy órán belül megírták, és természetesen vannak hibái, de mindez javítható. Használata oktatási célokra célszerű, bár mellesleg, miután egy kicsit befejezte, bármilyen rendszerbe beágyazhatja, és élvezheti a munkáját)).

    Hálás lennék, ha a megjegyzésekben felajánlaná a saját lehetőségeit ennek a problémának a megoldására - végtelen egymásba ágyazási szintű kategóriák rendezésére.

    Egyetlen oldal sem teljes navigáció nélkül, vagy ahogy a "webhely menüt" is nevezik. Tehát a webhely menüje lehet egyszintű és többszintű fa formájában. Ha nincs különösebb nehézség az egyszintű menü végrehajtása során, akkor a létrehozáskor többszintű menü jól kell gondolkodni.

    Ebben a feladatban a legfontosabb, hogy többszintű menünkhöz adatbázist tervezzünk. Hozzunk létre egy táblázatot a Kategóriák három mezővel azonosító , cím , szülő ahol:

    • ID - azonosító
    • Cím – Menü címe
    • Szülő – alapértelmezett kategória szülő 0

    A Szülő mező felelős a menüelágazásokért, ha Szülő = 0, akkor ez a kategória a szülőkategória. Ha gyerekeket szeretne hozzáadni a szülőkategóriához, a szülő mezőben meg kell adnia a kívánt szülő azonosítóját. Például:

    Táblázatok kategóriákkal

    Amint az a táblázatból látható, az autók szülőkategóriának két gyermeke van - a Mazda és a Honda, amelyeket a Szülő mező kapcsol össze. A Motorkerékpárok kategóriának pedig két leszármazottja van - ez a Kawasaki és a Harley. Ugyanakkor a Hajók kategóriának nincsenek leszármazottai. Remélem érti a kategóriák összekapcsolását.

    Ezután a szavakról a gyakorlatra térünk át. Hozzuk létre a Kategóriák táblát. TÁBLÁZAT LÉTREHOZÁSA, HA NEM LÉTEZIK "kategóriák" ("azonosító" int(10) előjel nélküli NOT NULL AUTO_INCREMENT, "title" varchar(255) NOT NULL, "parent" int(10) előjel nélküli NEM NULL, ELSŐDLEGES KULCS ("id") ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ; -- -- A `categories` táblázat adatainak kiíratása -- INSERT INTO `categories` (`id`, `title`, `parent`) ÉRTÉKEK (1, "Autók", 0), (2, "Motorkerékpárok", 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, "Csónakok", 0), (12, "Liftback", 8), (13, "Crossover", 8), (14, "fehér", 13), (15, "piros", 13), (16, "fekete", 13), (17, "zöld", 13), (18, Mazda CX, 3 ), (19, Mazda MX, 3); A munkaalgoritmus a következőkből áll: Kapcsolatot hozunk létre az adatbázissal A munka eredménye Többszintű menü PHP-ben + MySQL rendszergazdáknak

    Ha használni szeretné ezt a menüt az oldalad adminisztrációs panelén át kell írnod ​​pár függvényt tplMenu() , showCat() .

    Munka eredménye Válasszon Autók → Mazda →→ Mazda 3 →→→ Sedan →→→ Ferdehátú →→ Mazda 6 →→→ Liftback →→→ Crossover →→→→ Fehér →→→→ Piros →→→ Fekete →→→→ Zöld → → Mazda CX → → Mazda MX → Honda motorkerékpárok → Kawasaki → Harley Boats

    A következő feladat a végtelen egymásba ágyazás kategóriáinak elkészítése PHP segítségével. Több oldalt megmászva sok megoldást találtam, de megértésem szerint nem mindegyik elérhető, mert. a programozás szintje ott magasabb, mint az enyém. Ezért a legegyszerűbb, talán nem a legelegánsabb, de működő megoldást találtam.

    Először is nézzük meg, mi van az adatbázisban

    • id - kategóriánk azonosítója
    • kategória — kategória neve
    • category_id – a szülőkategória azonosítója. Meg lehetett hívni a parent_id-t, de ez ismerősebb számomra
    • lvl — kategória egymásba ágyazási szintje. Kialakulásához szükséges...
    • Minden, amit elmaszatolnak, nem használ neked, mert vannak olyan információk, amelyek számomra személyesen szükségesek, és hogy ne vezessenek félre - töröltem ezeket a felesleges információkat.
    Kategóriák megjelenítése itt

    Nincs itt semmi különös, ha kérdésed van, írd meg kommentben, és akit nem igazán érdekel, hogy mi van itt, annak javaslom, hogy azonnal nézze meg az eredményt

    Ha nem érted, akkor csak az lvl mezőre van szükségünk az adatbázisban, hogy tudjuk, mennyi "-"-t kell tenni a kategóriák neve elé. Persze van rafináltabb módszer lvl nélkül, de tovább Ebben a pillanatban Egyetlen megoldásom van. Ahogy változik, frissítem a cikket.

    Kategóriák megjelenítése itt
    • És itt van egy másik megoldás, amikor nem formában, hanem listában kell megjeleníteni.

      Itt már nincs szükségünk lvl-re, így kevesebb a kód. És lent az eredmény