Bugün size MySQL'de hiyerarşik bir ağacın nasıl oluşturulacağını anlatacağım.

Bu tür ağaçlar, örneğin bir çevrimiçi mağazada dinamik bir sitenin kategorilerini oluştururken veya bir gönderideki yorumları görüntülerken kullanılır.

Genel olarak mümkün olan her yere inşa edilirler. Önemli olan onu doğru bir şekilde oluşturmak ve uygulamaktır.

Hiyerarşik bir ağaç oluştururken en önemli şey doğru veritabanı yapısıdır! Örneğin, site kategorilerinin depolandığı veritabanının yapısını düşünün. Basit bir örnek olarak tablonun 3 alanı olacaktır:

  • kimlik - kategori anahtarı
  • parent_id — üst kategorinin kimliği
  • ad – bölüm adı
  • PHPMyAdmin'de bir SQL sorgusu çalıştırarak bir tablo oluşturalım:

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

    Şimdi tablomuzu kayıtlarla doldurmamız gerekiyor. Sonuç olarak şöyle bir tablo elde etmelisiniz:

    Bir test tablosunu aşağıdaki sorguyla doldurabilirsiniz:

    `Kategorilere` (`kimlik`, `ebeveyn_kimliği`, `ad`) EKLEYİN DEĞERLER (1, 0, "Bölüm 1"), (2, 0, "Bölüm 2"), (3, 0, "Bölüm 3" ), (4, 1, "Bölüm 1.1"), (5, 1, "Bölüm 1.2"), (6, 4, "Bölüm 1.1.1"), (7, 2, "Bölüm 2.1"), (8 , 2, "Bölüm 2.2"), (9, 3, "Bölüm 3.1");

    Ve şimdi dikkat! Daha sonra, mantıksal olarak, her bir kategoriyi ve onun alt kategorisini seçmek için veritabanından bir döngü içinde seçimler yapmanız gerekir. ANCAK! Veritabanında birkaç kategorinin olması sorun değil, bu da prensipte doğru değil. Site bir çevrimiçi mağazaysa ve yüz kategorisi ve aynı sayıda alt kategorisi varsa ne olur? O zaman bela! Veritabanına bilinmeyen sayıda sorgu yapılması sitenin yavaşlamasına veya MySQL sunucusunun tamamen çökmesine neden olacaktır.

    Tüm kategorileri ve bunların alt kategorilerini seçmek için yalnızca bir veritabanı sorgusu kullanabilirsiniz.

    Bir istekte bulunalım ve daha fazla çalışma için uygun bir dizi oluşturalım.

    //Veritabanından veri seçin $result=mysql_query("SELECT * FROMcategory"); //Veritabanında kayıtlar varsa, bir dizi oluştururuz if (mysql_num_rows($result) > 0)( $cats = array(); //Döngüde bölümlerden oluşan bir dizi oluştururuz, anahtar id olacaktır ana kategorinin yanı sıra bir dizi bölüm için anahtar kategori kimliği olacaktır while($cat = mysql_fetch_assoc($result))( $cats_ID[$cat["id"]] = $cat; $cats[$ cat["parent_id"]][$cat["id"]] = $cat; ))

    Kategoriler tablosundan tüm verileri seçiyoruz ve $cats ilişkisel bir dizi oluşturuyoruz, anahtar ana kategorilerin kimliği olacak.

    Şimdi bir ağaç yapacağız. Oluşturmak için özyinelemeli bir işlev kullanacağız.

    Hiyerarşik ağaç aşağıdaki yapıya sahip olacaktır:

    • Bölüm 1
      • Bölüm 1.1
        • Bölüm 1.1.1
      • Bölüm 1.2
    • Bölüm 2
      • Bölüm 1.1
      • Bölüm 1.2
    • Bölüm 3
      • Bölüm 3.1

    Özyinelemeli bir fonksiyon oluşturalım build_tree(). Kesinlikle herhangi bir yuvalamanın hiyerarşik ağacımızı oluşturacaktır.

    Function 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 ][$yalnızca_ebeveyn]; $ağaç .= "
    • ".$cat["isim"]." #".$cat["id"]; $tree .= build_tree($cats,$cat["id"]); $tree .= "
    • "; ) $ağaç .= "
    "; ) yoksa null değerini döndürür; $ağaç değerini döndürür; )

    İşlev bir dizi bölüm ve bölüm kimliğini alır. Döngüde alt kategoriler üzerinden geçiyoruz ve eğer daha fazla bölümleri varsa, işlev yeni parametrelerle (yeni bir bölüm dizisi ve oluşturulması gereken bölümün kimliği) yeniden başlatılır. Herhangi bir yuvalama ağacı bu şekilde oluşur!

    Bir ağaç oluşturmak için koda şunu yazarız:

    Echo build_tree($cats,0);

    Böylece, iki adımda web sitesi bölümlerinin hiyerarşik bir ağacını oluşturduk ve kaç bölüm olduğu önemli değil!

    UPD Kategori kimliğini bilerek ters sırada bir kategori ağacına ihtiyacınız varsa, o zaman işlevi kullanmanız gerekir:

    Function 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"]; )

    Bu işlev, anahtarı kategorinin kimliği ve yukarı çıkmanız gereken kategorinin kimliği olan bir dizi kategoriyi alır.

    Böyle bir ağaç oluşturmak için build_tree işlevini aşağıdaki parametrelerle çalıştırın:

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

    Sorularım var? Yorumlarda sorun

    28 Mayıs 2016

    Web uygulamaları geliştirirken çoğu zaman verileri ağaç şeklinde temsil etme ihtiyacıyla karşılaşırız. Aynı çevrimiçi mağazayı oluştururken, ürün kategorilerinin doğrusal yapısı yalnızca küçük projeler için uygundur. Çoğu zaman, kategorileri iç içe yerleştirebilmek istersiniz. Diğer durumlarda, örneğin bir dosya yöneticisi oluşturuyorsanız, kategoriler olmadan bunu yapmak daha da zordur.
    Bu yazımda size mysql'de bir tablo oluşturmaktan başlayıp, ağacı tarayıcıda görüntülemekle biten web sitenizde nasıl kolayca güzel bir veri ağacı oluşturabileceğinizi anlatacağım. Client üzerinde jstree kütüphanesini kullanacağız ve basit sunucu kodunu kendimiz yazacağız.

    Ne yapacağız ve bunun sonucunda ne elde edeceğiz?

    Örnek olarak, defalarca bahsedilen bir çevrimiçi mağazayı ele alalım ve onun için bir ürün kategorileri ağacı oluşturalım. Geleneksel olarak bilgisayar ekipmanı ticareti yapacağız. Öncelikle mysql'de bir kategori tablosu oluşturacağız, ardından katalog sayfası için işaretlemeyi çizeceğiz, js kodunu yazacağız ve son olarak veritabanına giren ve kategorileri müşteriye gerekli formatta gönderen bir php betiği yazacağız. Ve hemen bir bağlantı

    Kategori tablosu oluşturun

    Keyfi olarak dallara ayrılmış bir kategori yapısı oluşturmak için yalnızca bir tabloya ihtiyacımız var. Buna kategoriler adını verelim ve içinde 4 alan oluşturalım: id, kategori, parent_id ve number. id birincil anahtar olacak ve otomatik olarak artacaktır, kategori kategorinin adıdır, parent_id üst kategorinin kimliğidir, sayı üstteki kategorinin seri numarasıdır.

    Açıklayayım: Örneğin 3 ürün kategorimiz var, ana kategori dizüstü bilgisayarlar ve 2 tane daha içeriyor - Acer ve Lenovo. Tabloda şöyle görünecek:
    kimlik, kategori, parent_id, sayı
    1, Dizüstü Bilgisayarlar, 0, 1
    2, Acer, 1, 1
    3, Lenova, 1, 2
    Kök kategorilerin parent_id = 0 olacağı konusunda hemfikir olalım. Kategorilerin istenilen sırayla görüntülenmesini düzenlemek için sayı alanı gereklidir, Acer'ın her zaman ilk sırada olacağını garanti etmiyoruz, bu nedenle değiştirebilmeniz gerekir. Görüntüleme sırası. Her alt kategorinin 1'den başlayarak kendi numaralandırması vardır.

    Hiyerarşinin nasıl oluşturulduğunu daha iyi görmek için MySQL'de bir tablo oluşturun ve onu test verileriyle doldurun. Her ikisinin de sql kodu aşağıdadır. Her zamanki gibi veritabanını webdevkin olarak adlandıracağız.

    Kategori tablosu yapısı webdevkin'i kullanır; tablo kategorileri oluştur (id int(10) unsigned null değil auto_increment, kategori varchar(255) null değil, parent_id int(10) unsigned null değil, sayı int(11) unsigned null değil, birincil anahtar (id)) motor = innodb auto_increment = 18 avg_row_length = 963 karakter kümesi utf8 harmanla utf8_general_ci; Test verileri webdevkin'i kullanır; İSİMLERİ AYARLAYIN "utf8"; INSERT INTO kategoriler(`kimlik`, `kategori`, `ebeveyn_kimliği`, `sayı`) DEĞERLER (1, "Dizüstü Bilgisayarlar", 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, "Akıllı telefonlar", 0, 2), (9, "iPhone", 8, 1), (10, "Samsung", 8, 2), (11, "LG" , 8, 3), (12, "Vertu", 8, 4), (13, "Bileşenler", 0, 3), (14, "İşlemciler", 13, 1), (15, "Bellek", 13 , 2), (16, "Video kartları", 13, 3), (17, "Sabit sürücüler", 13, 4);

    Artık her zamanki phpMyAdmin-e veya dbForgeStudio'daki kategoriler tablosuna bakabilir ve mini uygulamamızı oluşturmaya devam edebilirsiniz.

    Proje yapısı

    Projenin kökünde index.html ve 4 basit klasörümüz olacak: img, css, js ve php. İmg, bir resim yükleme.gif içeriyor. Kategori ağacı sunucudan yüklenirken site ziyaretçilerine gösterilecektir. Css klasörü, sayfamız için stillerin bulunduğu main.css dosyasını ve jstree kütüphanesi için stilleri ve görüntüleri içeren jstree klasörünü içerir.

    Eski günlerin hatırına, js klasörünü satıcı ve modüllere böleceğiz. İlk klasör jquery ve jstree kütüphanelerini içerecektir. Açıklığa kavuşturayım; jquery sadece bizim için değil aynı zamanda jstree'ye bağımlılık olarak da gereklidir. Modüller klasöründeki tek dosya, uygulamanın ana js betiği olan main.js'dir. Tüm sunucu işlerini yapacak olan index.php dosyasını php klasörüne göndereceğiz.

    Bu sefer konunun önce sunucu tarafından bahsedip, daha sonra istemci tarafına geçmek daha uygun. Bu nedenle, kategori tablosundan gerekli formatta verilerin nasıl çıkarılacağına bakalım - php/index.php dosyası

    Sunucu kodu - index.php

    Ne yapmamız gerekiyor?

    • 1. Veritabanına bağlanın
    • 2. Kategorilerin bir listesini çıkarın
    • 3. Bilgileri tarayıcıya gönderin

    Liste basittir ve uygulamada herhangi bir sorun olmamalıdır. Dosyanın başında veritabanına bağlanmak için gerekli sabitleri bildireceğiz.

    // Gerekli sabitleri tanımlayın define("DB_HOST", "localhost"); define("DB_USER", "kullanıcı"); define("DB_PASSWORD", "şifre"); define("DB_NAME", "webdevkin");

    Daha sonra mysqli kullanarak veritabanına bağlanmak için bir fonksiyon yazıyoruz.

    // Veritabanı işlevine bağlanın connectDB() ( $errorMessage = "Veritabanı sunucusuna bağlanılamıyor"; $conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); if (!$conn) yeni İstisna atarsa($ errorMessage ); else ( $query = $conn->query("set names utf8"); if (!$query) throw new Exception($errorMessage); else return $conn; ) )

    Daha sonra tablodan kategori listesini çıkarmamız gerekiyor. Burada biraz kendimizin önüne geçmemiz gerekiyor. Jstree kütüphanesi json'u girdi olarak kabul eder. Kabul edilebilir formatlar kütüphanenin jstree.com web sitesinde açıklanmıştır. Bizim için en uygun olanı alacağız ve hazırlanan verileri hemen sunucudan göndereceğiz. Bu format şuna benzer:

    [ ( "id" : "ajson1", "parent" : "#", "text" : "Basit kök düğüm" ), ( "id" : "ajson2", "parent" : "#", "text" : "Kök düğüm 2" ), ( "id" : "ajson3", "parent" : "ajson2", "text" : "Çocuk 1" ), ( "id" : "ajson4", "parent" : "ajson2" , "text" : "Çocuk 2") ), ]

    Örnek dokümantasyondan alınmıştır, ancak kolaylık olması açısından kimlik olarak veritabanımızdaki kimliği kullanacağız - ajson öneki olmayan bir sayı. Veritabanı tablosundan kategori alma fonksiyonuna geçelim

    // Veritabanından kategorileri alma işlevi getCategories($db) ( $query = " id AS `id`, IF (parent_id = 0, "#", parent_id) AS `parent', kategori olarak `text` FROM kategoriler ORDER BY `ebeveyn`, `sayı` "; $data = $db->query($query); $categories = array(); while ($row = $data->fetch_assoc()) ( array_push($categories, array) ( "id" => $satır["id"], "parent" => $satır["parent"], "text" => $satır["metin"])); ) return $kategoriler; )

    Burada, kategoriler tablosunda düzenli bir seçim sorgusu çalıştırıyoruz, gerekli 3 alanı çıkarıyoruz ve aynı zamanda bunları hafifçe gerekli formata dönüştürüyoruz. İd'yi değişiklik yapmadan iletiyoruz, parent_id'yi parent olarak döndürüyoruz ve kök kategoriler için # döndürüyoruz. Ve kategori alanı metin olarak aktarılacaktır. Veriler alındı, geriye kalan tek şey onu json'a dönüştürüp tarayıcıya göndereceğimiz bir diziye koymak. Bu, ana komut dizisinde görülebilir

    Deneyin ( // Veritabanına bağlanın $conn = connectDB(); // Diziden veri alın GET $action = $_GET["action"]; switch ($action) ( case "get_categories": $result = getCategories( $ bağlantı); break; default: $result = "bilinmeyen eylem"; break; ) // İstemciye başarılı bir yanıt döndürün echo json_encode(array("code" => "success", "result" => $result) ); ) catch (Exception $e) ( // İstemciye bir hata yanıtı döndürün echo json_encode(array("code" => "error", "message" => $e->getMessage())); )

    Nelere dikkat etmeniz gerekiyor. Bizim özel durumumuzda, get parametresini eyleme geçirmek gereksiz gibi görünüyor, ancak bu, index.php dosyası yalnızca tek bir göreve hizmet ettiği sürece, yani bir kategori listesi döndürmek için geçerlidir. Ağaç işlevselliğinin geliştirilmesi, özellikle istemcide sürükle ve bırak uygulamasının uygulanması ve sunucudaki ilgili verilerin güncellenmesiyle birlikte yakında bir makale yayınlanacaktır. Burada, gerekli eylemin göstergesi olarak bir get parametresinin iletilmesinin oldukça uygun bir konu olduğunu göreceğiz.

    Ve müşteriye verilen yanıt hakkında. Kod alanı her zaman isteğin durumunu (başarı veya hata) gösterir. Başarılı olması durumunda kategori dizisi sonuç alanına döndürülür; herhangi bir sorun olması durumunda mesaj alanına hata mesajı gönderilir.

    Uygulamamızın sunucu kısmı bu kadar, client kısmına geçelim.

    Katalog sayfamızın işaretlemesi index.html'dir

    Eğer uygulamanın demosuna daha önce bakmışsanız işaretlemenin son derece basit olduğunu göreceksiniz. 2 ana kap vardır: solda - kategori ağacı için, sağda - ürün listesi için yer tutucu. Head bölümü aşağıdaki kodu içerecektir:

    Webdevkin. Javascript, php ve mysql'deki kategori ağacı

    Ürün listesi

    Ve main.css'e biraz işaretleme ekleyin

    Gövde ( yazı tipi ailesi: Ubuntu; yazı tipi boyutu: 16 piksel; yazı tipi ağırlığı: 400; ) .container ( konum: göreceli; genişlik: 960 piksel; kenar boşluğu: 0 otomatik; ) . sütun ( ekran: satır içi blok; dikey hizalama : üst; ) .kategoriler ( genişlik: 30%; )

    Html/css ile işimiz bitti ve şimdi en ilginç kısma geçelim; ağacı oluşturmak için kullanılan javasctipt kodu. Planlanan tüm işlevleri bir araya getireceğimiz yer burasıdır.

    main.js - uygulama başlatma

    Örneğin ön tarafta bir çevrimiçi mağaza için sepet oluşturma veya yerel javascript kullanarak yerleşik widget'lar hakkında önceki makaleleri okuduysanız, js kod şemamın tüm durumlar için yaklaşık olarak aynı olduğunu hatırlayabilirsiniz.

    Bunu burada da uygulayalım: kapatmaya dayalı bir js modülü oluşturun, gerekli dom öğelerini önbelleğe alın, birkaç özel yöntem ve bir genel yöntem yazın - uygulama başlatma yöntemi.

    Modül çerçevesi "katı kullanın"; // Uygulama modülü var app = (function($) ( // Gerekli değişkenleri başlatın var ajaxUrl = "/php", ui = ( $categories: $("#categories"), $goods: $("#goods" ) ); // Kategori ağacının jstree fonksiyonunu kullanarak başlatılması _initTree(data) ( // ... ) // Kategorilerin sunucu fonksiyonundan yüklenmesi _loadData() ( // ... ) // Uygulama fonksiyonunun başlatılması init() ( _loadData( ); ) // Dışa aktar return ( init: init ) ))(jQuery); jQuery(document).ready(app.init);

    Son satırda görebileceğiniz gibi belgeyi yükledikten sonra app.init() yöntemini çağırıyoruz, o da sunucudan veri yükleyerek ağaç oluşturma yöntemine aktarıyor. AjaxUrl'de sunucu betiğimizin adresini yazıyoruz; ui nesnesinde iki dom öğesi önbelleğe alınacaktır.

    Sunucudan veri alınıyor - yöntem _loadData() // Sunucudan kategoriler yükleniyor function _loadData() ( var params = ( action: "get_categories" ); $.ajax(( url: ajaxUrl, method: "GET", data: params, dataType: "json", başarı: function(resp) ( // Kategori ağacını başlat if (resp.code === "success") ( _initTree(resp.result); ) else ( console.error("Error) sunucudan veri alınıyor: ", resp.message); ) ), error: function(error) ( console.error("Error: ", error); ) )); )

    Burada en yaygın Ajax isteğini bir sunucu komut dosyasına yazıyoruz, kategorilerle birlikte veri alıyoruz ve başarılı olursa bunu ağaç başlatma işlevi _initTree()'ye aktarıyoruz. Sunucudan json formatında veri aldığımızı hatırlıyoruz, bu nedenle hemen dataType: "json"u belirteceğiz. Ve sonuç alanına gerekli bilgiler gelecektir, bu nedenle resp.result'u tam olarak _initTree'ye aktarıyoruz. Hataları istediğiniz şekilde ele alabilirsiniz; örneğin, onları yalnızca konsola atacağız.

    jstree kullanarak _initTree işlevinde bir ağaç oluşturmak // jstree işlevini kullanarak kategori ağacını başlatmak _initTree(data) ( ui.$categories.jstree(( core: ( check_callback: true, multiple: false, data: data ), eklentiler: [" dnd"] )).bind("changed.jstree", function(e, data) ( var kategori = data.node.text; ui.$goods.html("Kategorideki ürünler " + kategori); console. log( "düğüm verileri: ", veriler); )); )

    Ve ihtiyacın olan tek şey bu! Görsel olarak uygulamanın en karmaşık kısmı son derece basit görünüyor. Belirli bir dom öğesine bazı parametrelerle birlikte jstree yöntemini uygulamanız yeterlidir. Bizim durumumuzda verinin kendisini veri alanına aktarıyoruz, multiple: false çoklu seçime ihtiyacımız olmadığını, check_callback: true ise ağacı değiştirdikten sonra başka bir şey yapmak istediğimizi gösteriyor.

    Eklentiler alanında istenilen çörekleri bir dizi halinde listeliyoruz. Şimdi dnd'ye odaklanalım - sürükle ve bırak - ağaç yapısını fareyle değiştirme yeteneği ekleyelim. Bu çok kullanışlı bir şey ama henüz işlevsel değil. Tarayıcıda ağaçla dilediğiniz kadar oynayabilirsiniz ancak sayfayı yeniledikten sonra eski dizin yapısını göreceğiz. Veriler sunucudan alındığından ve istemci olaylarında MySQL'i güncellemek için herhangi bir kod yazmadığımızdan bu mantıklıdır. Aşağıdaki makalelerden biri buna ayrılacak, ancak şimdilik tarayıcıdaki fareyi kullanarak kategorileri hareket ettirerek oynayacağız.

    Ve son olarak, bağlama yöntemini kullanarak ağaçtaki bir değişiklik olayını bazı yararlı eylemlerle ilişkilendiririz. Örneğimizde, sadece kategorinin adını içeren bir yazı görüntüleyeceğiz, ancak gerçek bir uygulamada ürün listesini sunucudan çekmeye değer. Kategori = data.node.text nereden geldi? Tarayıcı konsolunuzu açın ve seçilen düğümle ilgili başka hangi verilerin elimizde olduğunu görün.

    Toplam

    Bu makalede, çevrimiçi bir mağaza işletmek için tam teşekküllü bir katalog oluşturmadık - fikir bu değildi. Ağaç gibi kullanışlı bir yapının baştan sona mümkün olduğunca basit bir şekilde nasıl inşa edileceğine odaklanmak istedim. Ağacın kendisiyle daha yakın çalışma ve istemci eylemlerinin sunucuyla senkronizasyonunun yanı sıra bir kategoriye tıkladığınızda bir ürün listesi oluşturma gibi bazı noktalar kasıtlı olarak atlandı. İlk seçenek için ayrı bir makale yayınlayacağım.

    GÜNCELLENMİŞ: Tek tek ağaç öğelerinin sürükle ve bırak yöntemini kullanarak fare ile nasıl taşınacağını ve bu verilerin sunucuyla nasıl senkronize edileceğini gösteren bir makale yayınladım. İstemci ve sunucu hakkında küçük bir kod - ve işte! Bağlantı hemen aşağıda 4 numarada.

    Ve böylece başlangıçta neyle çalışacağımızı ve neye ihtiyacımız olacağını anlatacağım.
    Sistem: PHP 5 ve üzeri, mySQL 4 ve üzeri
    Yardımcı sınıflar: dbsql.class.php (veritabanı ile çalışmak için sınıf)
    İç içe geçmiş kategorilerin sınıfı: classTreeCategory.php (doğrudan ana sınıf, listesi ve açıklamaları aşağıdadır.

    Veritabanında aşağıdaki yapıya sahip bir tablo oluşturuyoruz:

    Kodu görüntüle MYSQL

    Bu tablo bir kimlik alanı içerir - kategorinin seri numarası, podcat - birinci derece kategoriler için sıfır değerine sahiptir veya ana kategorinin kimliği, adı - kategorinin adı.

    Kategorilerin alt kategorilerle birlikte bir listede görüntülendiği sınıfın nasıl çalıştığına dair bir örnek:

    Kodu görüntüle PHP

    include ("dbsql.class.php" ); include ("classTreeCategory.php" ) ; $DB = new DB_Engine("mysql" , $settings [ "dbHost" ] , $settings [ "dbUser" ] , $settings [ "dbPass" ] , $settings [ "dbName" ] ) ; // erişim verilerini göstererek veritabanına bağlanın $category = new TreeCategory ($DB ) ; // veritabanıyla çalışmak için bir nesne olan kategori sınıfına geçin $kategori -> tablo = "kategori" ; // veritabanındaki kategorilerin bulunduğu tablonun adı $array = $category -> getCategory () ; // veritabanından tüm kategorileri ihtiyacımız olan sıraya göre sıralanmış ve iç içe yerleştirilmiş çok düzeyli bir dizi biçiminde alıyoruz $category -> outCategory ($array, "option" ) ; // kategorilerin çıktısını hazırlamak (HTML oluşturmak), kategorileri içeren bir diziyi geçirmek echo $category -> html ; // kategorilerin HTML adı olarak çıktısı

    Yukarıdaki örnekte görebileceğiniz gibi, her şey son derece basit, yeni bir $category nesnesi oluşturuyoruz, hangi veritabanı tablosuyla çalıştığımızı belirliyoruz: 'kategori', ardından tablodan zaten bir kategori olarak biçimlendirilmiş tüm kategorilerin bir listesini alıyoruz. tüm alt kategoriler dikkate alınarak hiyerarşik bir düzende dizilir ve düzenlenir. daha sonra diziyi, yalnızca tarayıcıda görüntülememiz gereken hazır HTML kodunu üreten outCategory() yöntemine aktarıyoruz.

    outCategory() yöntemi, gördüğümüz gibi, @array ve @string olmak üzere iki parametre alır; ilk parametrede tüm kategorileri içeren bir dizi, ikincisinde ise seçenek veya tablo değerini içeren bir satır vardır; bu değer, ne tür HTML kodunun gerekli olduğunu gösterir. oluşturulacak.
    Opsiyon değeri

    Kodu görüntüle HTML

    -kategori 1 --alt kategori 1 ---alt alt kategori 1 -kategori 2

    Bu HTML kodunu herhangi bir formun seçim alanına eklemek için.

    Tablo değeri aşağıdaki HTML kodunu oluşturur:

    Kodu görüntüle HTML

    Bu HTML kodu, tüm kategorilerimizi ve alt kategorilerimizi görüntüleyen bir tabloya eklemek için uygundur.

    Sınıfın ayrıca aşağıdaki yöntemleri vardır:
    deleteItem($id); — iç içe geçmiş olanlara rağmen bir kategoriyi siler
    delCategory($dizi, $id); — tüm iç içe geçmiş alt kategorileri içeren bir kategoriyi siler, $array — $category->getCategory() yöntemiyle hazırlanan tüm kategorileri içeren bir dizi, $id — silinecek kategorinin numarası
    öğe eklemek(); — Bir kategori eklemek istiyorsanız bu yöntem çağrılmalıdır ve bu yöntem, POST yöntemiyle iletilen verilerden değerleri okur, yani. $_POST dizisinden.
    $name=$this->PHP_slashes(strip_tags($_POST['name'])); // Kategori adı
    $podcat=intval($_POST['podcat']); // Ana kategorinin kimliği, eğer 0 belirtilirse kategori kökte olacaktır.
    updateItem() ; — önceki yönteme benzer, ancak bu yöntem kategoriyi, adını ve iç içe geçme düzeyini günceller.

    tablo = "kategori"; // kategori listesi seçme isteği, tablo adı * $category->outCategory($category->getCategory()); // kategorilerin çıktısını hazırlamak (bir kategori dizisini sorgulamak) * echo $category->html; // kategorilerin HTML adında çıktısı * */ /** * Çalıştığımız tablonun dökümü * * DROP TABLE IF EXISTS `category`; * CREATE TABLE `category` (* `id` int(11) NOT NULL auto_increment, * `podcat` int(11) NOT NULL, * `name` varchar(255) NOT NULL, * PRIMARY KEY (`id`), * ANAHTAR `id` (`id`) *) MOTOR=MyISAM VARSAYILAN KARAKTER SETİ=utf8; * */ class TreeCategory ( /** * Veritabanındaki sorgu dizesi */ var $tablo; /** * Veritabanıyla çalışmak için arayüz */ var $DB; /** * İç içe geçmiş alt kategorilere sahip kategori dizisi */ var $arrayCat; / ** * Çıktı alırken kategori adından önceki tire sayısını otomatik olarak say */ var $countPodcat; /** * Alt kategorileri olan kategorilerin çıktısını almak için HTML kodu */ var $html; /** * Bir sonuç elde ederiz veritabanıyla çalışmak ve onu yerel bir değişkene koymak için arayüz */ function __construct($DB) ( $this->DB=$DB; $this->component=$_GET["component"]; ) /** * Kategorilerin bir listesini alır, bunları sıralar ve iç içe diziler vb. içeren bir diziye yerleştirir. * @return dizi kategorisi */ function getCategory () ( $all = $this->DB->getAll("SELECT * FROM `( $this->table)` ORDER BY `id` ASC"); $yol = dizi(); if(count($all)>0) ( foreach($all as $item): if($item["podcat "]==0)$sort[$item[ "id"]]=$item; if($item["podcat"]>0) ( if(isset($path[$item["podcat"]]) ) ( $str=$sort"; foreach( $path[$item["podcat"]] as $pitem): $rep=$item["podcat"]; $str.="[$pitem]"; uçtan uca; $str.="[($item["podcat"])]"; $str.="[($item["id"])]"; $str.="=$item;"; eval($str); foreach($path[$item["podcat"]] as $pitem): $path[$item["id"]]=$pitem; uçtan uca; $yol[$item["id"]]=$item["podcat"]; ) else ( $sort[$item["podcat"]]["sub"][$item["id"]]=$item; $path[$item["id"]]=$item["podcat" ]; )) endforeach; ) $this->arrayCat=$sort; return $this->arrayCat; ) /** * Kategorileri yazdırır, tamamlanmış HTML'yi $this->html içine yerleştirir * @param array Kategoriler ve iç içe geçmiş alt kategoriler içeren dizi * @param string Çıktı, seçenek veya tablo için oluşturulan HTML kodunun türü */ function outCategory(&$ arrayCat, $type="option", $idSel=0) ( foreach($arrayCat as $sub) ( $this->countPodcat++; $this->outItem($sub, $type); if(!empty($sub) [" sub"]))$this->outCategory($sub["sub"], $type, $idSel); $this->countPodcat--; ) ) /** * HTML kodunu hazırlamak için yardımcı bir yöntem * @param array Kategorili dizi * @param string Çıktı, seçenek veya tablo için oluşturulan HTML kodunun türü */ function outItem($sub, $type="option", $idSel=0) ( for($i=0;$ icountPodcat;$i++) ( $out. = "-"; ) if($idSel==$sub["id"])$se="seçili"; else $se = ""; if($type=="option")$this->html.=" ($out) ($sub["name"]) "; if($type=="table")$this->html.= ($out) ($sub["name"]) HTML; ) function delCategory(&$a_tree,&$id=0) ( foreach($a_tree as $sub) ( if($sub["id"]$id and isset($sub["sub"]))$this- >delCategory($sub["sub"],$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 as $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(strip_tags($_POST["name"])); $podcat=intval($_POST["podcat"]); $id=intval($_POST["id"]); $sql =GÜNCELLEME `( $this->table)` SET `name` = "($name)", `podcat` = "($podcat)" WHERE `id`="($id)" LIMIT 1; "; $this->DB ->execute($sql); ) function addItem() ( $name=$this->PHP_slashes(strip_tags($_POST["name"])); $podcat=intval($_POST["podcat"]); $ id=intval($_POST["id"]); $sql="INSERT INTO `($this->table)` (`id`,`podcat`,`name`) DEĞERLER ("", "$podcat" , "$isim");"; $this->DB->execute($sql); ) function deleteItem($id) ( $id=intval($id); $sql = SİL `($this->table)` WHERE `id` = "($id)" LIMIT 1"; $DB- >execute($sql); başlık("Konum: ?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 == "strip") ( return stripslashes($string); ) else ( die("PHP_slashes'te hata (karışık, ekle | şerit)"); ) )) )

    Bütün ders bir saat içinde yazıldı ve elbette bazı eksiklikler var ama bunların hepsi düzeltilebilir. Eğitim amaçlı kullanılması tavsiye edilir, ancak biraz bitirerek onu herhangi bir sisteme entegre edebilir ve çalışmasının tadını çıkarabilirsiniz)).

    Yorumlarda bu soruna kendi çözümlerinizi önerirseniz - sonsuz düzeyde yuvalama kategorileri düzenlerseniz minnettar olurum.

    Bir sonraki görev PHP kullanarak sonsuz iç içe yerleştirme kategorileri oluşturmaktır. Birkaç sitede gezindikten sonra birçok çözüm buldum, ancak bunların hepsi benim anlayışıma uygun değil çünkü... Oradaki programlama seviyesi benimkinden daha yüksek. Bu nedenle en basit, belki de en zarif olmayan ama işe yarayan çözümü buldum.

    Öncelikle veritabanımda ne olduğuna bir bakalım

    • id - kategorimizin tanımlayıcısı
    • kategori – kategori adı
    • categor_id — üst kategorinin tanımlayıcısı. Buna parent_id diyebilirsin ama bu bana daha tanıdık geldi
    • lvl — kategori iç içe geçme düzeyi. Formasyon için gerekli...
    • Üstü örtülen her şeyin sana faydası yok çünkü... Orada kişisel olarak benim için gerekli olan bilgiler var, sizi yanıltmamak adına bu gereksiz bilgileri sildim.
    Kategoriler şurada görüntüleniyor

    Burada söylenecek fazla bir şey yok, sorularınız varsa yorumlara yazın, burada yazılanları pek umursamayanlar için hemen sonuca bakmanızı öneririm

    Anlamadıysanız kategori adlarının önüne kaç tane “-” koyacağımızı bilmek için veritabanındaki lvl alanına ihtiyacımız var. Elbette lvl olmadan daha karmaşık bir yöntem var ama şu anda sahip olduğum tek çözüm bu. Durumlar değişir değişmez, makaleyi güncelleyeceğim.

    Kategoriler şurada görüntüleniyor
    • Ancak formda değil listede görüntülemeniz gerektiğinde işte size başka bir çözüm.

      Burada artık lvl'ye ihtiyacımız yok, dolayısıyla daha az kod var. Ve sonuç aşağıda

      Geçerli kaydın ebeveyninin kimliğini saklayan "ebeveyn" türündeki bir alanın modele eklenmesiyle oluşturulur. Kök kayıtlar için bu alanın değeri "-1"dir.

      Dikkat! Bir modelde "ebeveyn" türünde yalnızca bir alan olabilir.

      Alt sayfalardan oluşan bir menü oluştururken ağacın basit kullanımına bir örnek.

      Bağlantılı ağaç

      “Katalog -> katalog -> katalog -> ürün” veya “albüm -> albüm -> resim” gibi bir yapı oluşturmak için, “ana” alanı olan bir modeli başka bir modele bağlamanız gerekir; böylece ilk modelin son ebeveyni olur. model, diğer modellerin kayıtları için yabancı bir anahtardır.

      Çok düzeyli bir ürün kataloğu için bağlantılı ağaç oluşturma örneği.

      Sınıf Katalogları Modeli genişletir ( protected $name = "Katalog Bölümleri"; protected $model_elements = array(array("Active", "bool", "active", array("on_create" => true))), array("Name" , "char", "name", array("gerekli" => true)) array("Katalog", "parent", "parent", array("parent_for" => "Ürünler")), array(" Bağlantı", "url", "url"), array("Konum", "sipariş", "sipariş")); ) class Ürünler Modeli genişletir ( protected $name = "Katalog Ürünleri"; protected $model_elements = array(array) ("Aktif", "bool", "aktif", dizi("on_create" => doğru)) dizi("Ad", "karakter", "ad", dizi("gerekli" => doğru)) dizi ("Katalog bölümü", "enum", "parent", array("foreign_key" => "Kataloglar", "is_parent" => true)) array("Fiyat", "int", "price", array( "gerekli" => doğru)) array("Resimler", "çoklu_resimler","resimler"), dizi("Açıklama", "metin", "desc", dizi("zengin_metin" => doğru)) dizi ("Pozisyon", "sipariş", "sipariş")); )

      Özel ağaç yöntemleri

      Ebeveynlere ve çocuklara hızlı erişim için ağaçta özel yöntemler sağlanmıştır.

      • getParents($id) - bir dizi üst kayıt döndürür (ana alan değeri -1 olan kayda kadar). Ortaya çıkan dizide anahtarlar kayıtların ID'leri, değerler ise Model Kurulumu bölümündeki "$name_field" parametresine göre kayıtların isimleridir.
      • getChildren($id) - ağacın tüm dallarını yinelemeli olarak geçerek tüm alt kayıtların bir dizisini döndürür. Ortaya çıkan dizi önceki yönteme benzer şekilde oluşturulur.
      • displayBreadcrumbs($id, $url_first [, $url_field]) - iletilen kimliğe sahip girişin referans yolunu görüntüler. Formdaki bir dizi html etiketini döndürür
        "bağlantı -> bağlantı -> bağlantı -> yayılma". Giriş parametreleri: geçerli gönderinin kimliği, $url_first - URL'nin ilk kısmı,
        isteğe bağlı parametre $url_field - bu girdiye ilişkin metin bağlantısının depolandığı alanın adı ("katalog/oyuncaklar/" gibi bir URL oluşturmak için). Önceden yüklenmiş "Sayfalar" modeli için bağlantılar otomatik olarak "/page/4/" ve "/contacts/" (ilk bölüm olmadan) biçiminde oluşturulur.
      $katalog = $mv -> kataloglar -> findRecordById(43); //Ebeveyn kayıtları $parents = $mv -> kataloglar -> getParents($katalog -> id); //Çocuk girişleri $children = $mv -> kataloglar -> getChildren($catalog -> id); //Katalog bölümü için referans yolu echo $mv -> kataloglar -> displayBreadcrumbs($catalog -> id, "category", "url"); //Katalog ürünü için referans yolu echo $mv -> ürünler -> displayBreadcrumbs($product -> id, "category"); //Referans yolu Toys Balls Ball kırmızısı şeklinde olacaktır