Duyuruyu Kapat
Facebook Gözat
Twitter Gözat

Çok boyutlu dizi değişkenlerini sıralamak

Konu, 'PHP' kısmında HunTER tarafından paylaşıldı.

  1. HunTER

    HunTER ...

    Kayıt:
    15 Ağustos 2002
    Mesajlar:
    8,684
    Beğenilen Mesajlar:
    0
    Meslek:
    Web Programlama
    Şehir:
    İstanbul
    Bır rehber scrıptı yapmayı dusunuyorum ve soyle bır problemle karsı karsıyayım.. Dıyelımkı rehberın ana kategorılerı ve buna baglı alt kategorılerı var.. Ve bunlar dınamık olucak.. Yanı eklemeler yada duzeltmeler yapılabılınmelı.. Daha sonra bu dınamık ana ve alt kategorıler a dan z ye alfabetık olarak sıralanmalı.. Bır ornek vermem gerekırse

    Kod:
    Avukatlar
    	Ceza hukuku
    	Medeni hukuk
    Doktorlar
    	Diş Hekimleri
    	Diyetisyenler
    
    Oncelıkle sorum bu tıp bır yapıyı bunyesınde dınamık olarak barındarabılecek bır dızı degıskenı ve bu dızı degıskenını lısteleyecek kod nasıl olmalıdır?

    Dınamıkten kastım ornegın dızıye yenı bır deger eklenebılmelı ve varolan degıstırılebılmelı.. Ve hatta rehbere kayıt gırecek vatandas lıstelenen kategorıler arasında kendıne uygun bı deger bulamaz ıse form aracılıgyla yenı bır deger ekleyebılmelı?

    Bunun ıcın

    Kod:
    0;Avukatlar
    0;0;Ceza hukuku
    0;1;Medeni hukuk
    1;Doktorlar
    1;0;Diş Hekimleri
    1;1;Diyetisyenler
    
    Gıbı bır dosya olusturup scrıpt her calıstrırıldında bu dosyadakı satırları bır dızıye atmak mantıklımı? Boylece yenı bır deger ıcın dosyanın sonuna bı satır eklemek yeterlı olabılır.. Degıstırmek ıcınse once dosya dızıye alınır daha sonra degısıklık yapılır ve tekrar dosya dızıden yazılır..

    Aklıma gelen cozum bu baska bır alternatıfım varmı?
     
  2. mkarabulut

    mkarabulut Misafir

    Selamlar...
    1-Öncelikle veritabanı kullanmanı tavsiye ederim, çünkü dosya komutları ile uğraşmak ve bazı şeyleri elle yapmak yerine otomatik olarak yaptırabilirsin.

    2- Eğer veritabanı kullansaydın yine aynı şeyi söyleyecektim;
    Her kategorinin bir id bilgisi ile beraber ust kategorinisin id bilgisini saklamanı önerirdim. Böylece sınırsız bir alt kategori sistemi kurabilirdin.

    Gelelim senin sorununa,

    Kod:
    0;Avukatlar
    0;0;Ceza hukuku
    0;1;Medeni hukuk
    1;Doktorlar
    1;0;Diş Hekimleri
    1;1;Diyetisyenler
    
    şeklinde saklamak işini görür. Bunu dizi değişkende tutmak ve kullanmak için belki şöyle bi şeyler işini görür.
    PHP:
    <?
     
    //file komutuna dikkat,
     //her dosya satırı dizinin bir elemanı 
     //olacak şekilde bir diziye atılıyor içerik
     
    $filefile ("dosya.txt"); 
     
     
    //Bütün kayıtları tutacak dizimiz
     
    $records=array();

     foreach (
    $file as $line){
              
    //; karakterlerini ayır
              
    $parts=explode(";",$line);

              
    //şimdi burası önemli ,
              //dizinin eleman sayısına göre
              //derinliğini anlıyoruz
              //ama parts dizisinin 
              //en son elemanı hep kategori ismi

              
    if (count($parts)>2){
                       
    $records[$parts[0]][$parts[1]]=$parts[2];                 
              }  else {
                       
    $records[$parts[0]]=$parts[1];
              }
     }
    ?>

    Şimdi üstad bu kod sadece 1 derinlikli kategori sistemini destekliyor, ama sen sınırsız derinlikte bi kategori sistemi kurmak istersen bu kod işini göremeyecektir. Çünkü dikakt ettiğin üzere if kontrolünde sadece 2 den büyük olma kontrolü yapılıyor.

    Sınırsız alt kategori için bi şeyler önerecem ama 2. mesajda devam edeyim... :)
     
  3. mkarabulut

    mkarabulut Misafir

    Üstad 2. metod için bir struct (yapı ) kullanmanı tavsiye ederim ama php de struct olmadığı için (ya da var da ben mi bilmiyorum :)) class kullanacaz

    öncelikle şöyle bi class yapımız olacak

    class kategori {
    var $kategori_isim;
    var $kategori_id;
    var $ust_kategori_id;
    }

    Sonra malum for döngümüz içinde if kontolü yapmayacaz da şöyle bi şeyler yapacaz...

    foreach ($file as $line){
    //; karakterlerini ayır
    $parts=explode(";",$line);

    $len=count($parts);
    $kategori=new kategori;
    $kategori->kategori_isim=$parts[$len-1];
    $kategori->kategori_id=$parts[$len-2];
    $kategori->ust_kategori_id=$parts[$len-3];

    //Burası önemli
    //records dizisine atarken kolaylık olması için
    // records dizisinin indisini kategori id ile aynı yapıyoruz
    $records[$kategori->kategori_id]=$kategori;

    //ehe biraz performans yapalım :)
    unset($kategori);

    }
    ?>

    Üstad şimdi bunları böyle diziye attıktan sonra artık elinde şöyle bi dizi var :

    $records[0]=OBject;
    $records[1]=Object;
    $records[2]=Object;

    Yalnız dikkat ettinse, alt kategorilerin id numaraları da üst kategoriler ile çakışmamalı, dikkat edilmeli buna :)

    Ha şimdi istediğin bi katgoriye erişmek istersen mesela
    0 id li kategorinin alt kategorilerini listele

    foreach ($records as $record){
    if ($record->ust_kategori_id==0)
    echo $record->kategori_isim."<br>";
    }

    gibi...

    Ama dikkat ettiysen herhangi bi bilgi için bütün kategorileri araman gerekiyor. Bu 1 di..

    İkincisi her kategorinin id si birbrinden farklı olmalı ister alt kategori olsun ister üst kategori olsun bu 2 idi.

    Yani veritabanında ki auto_increment gibi bi şey lazım sana ayrıca dizi içinde istenen elemanları bulman için tüm diziyi taramak değilde yanlış hatırlamıyorsam bazı algoritmalar vardı bu işler için..

    Bunların hepsi veritabanlarında zaten kullanılıyor.

    Özet ; veritabanı kullanabilirsin hala :)
     
  4. HunTER

    HunTER ...

    Kayıt:
    15 Ağustos 2002
    Mesajlar:
    8,684
    Beğenilen Mesajlar:
    0
    Meslek:
    Web Programlama
    Şehir:
    İstanbul
    Ilgın ıcın saol.. Yukarda verdıgın algorıtmanın benzerını kafamda kurgulamıstım zaten.. Ama asıl merak ettgım bunun mantıklı olup olmıyacagıydıkı bunu da cevaplamıssın.. Bende scrıpt her cagrıldıgında bır dosyaya erısmenın performansı dusurecegını dusunmustum ama sanırım ıkıncı onerın olucak ozyınemelı fonksıyonlar kullanmaktansa bu tıp bıseyın daha kolay olucagını dusundum..

    Evet ıkıncı onerın ozyınelememı ? Oyleyse su konuyu bıraz acarmısın.. Cunku cıdden bu olaya gırdıgımde kafam karısmaya baslıyor.. Ayrıca ben kategorı adlarına tek bı noktadan hukmetmek ıstıyorum.. Asıl derdım bu.. Yanı ınsanların kafasına gore kategorı acmalarıda pek ısıme gelmez.. Yapmak ıstedıgım onlara once bır cekmelı menu aracılıgı ıle butun kategorılerı sunmak eger aradıklarını bulamazlarsa kendı kategorılerını olusturmalarını saglamak..

    Bırde bu tablo kullanımı soz konusu oldugunda sanırım kategorılerı ıceren bır tabloyada ıhtıyacım olucak.. Boyle bır tablonun yapısı nasıl olmalı?
     
  5. HunTER

    HunTER ...

    Kayıt:
    15 Ağustos 2002
    Mesajlar:
    8,684
    Beğenilen Mesajlar:
    0
    Meslek:
    Web Programlama
    Şehir:
    İstanbul
    Benım son yazdıgım mesajı senın son yazdıgın mesajın onune getırerek degelendır.. Cunku sanırım sen benden sonra baslayıp bende once bıtırmıssın mesajı :)

    Sımdı elımde soyle bır ornek var.. Bır web forum.. Agac yapısında ve sınırsız sayıda alt mesaj eklenebılıyor.. Senınkıne benzer bır class kullanmıs ama sanırım class ozyınemelı bır fonksıyonun uzerınde yapılandırılmıs.. Ayrıca bır tabloda sadece id leri ve gereklı dıger alanları baska bır tabloda ıse mesajları saklamıs.. Bunu performansı artırmak ıcın yaptıgını soyluyor..

    Burdan hareketle bu ornek bıraz kurcalanırsa bır rehber scrıptı ıcın sınırsız derınlıklı bır yapı olusturulabılır.. Ama tam olarak benım ıstedıgım sey olurmu bılemem.. Ornegın bu yapı ıcınde tek bır kategorının degerını degıstırmek ıcın tabloda o degere aıt tum satırları degıstırmek gerekıyor.. Yada bu durumda benım kategorıler ve onların degerlerı ustundekı hakımıyetım sona erıyor..

    Sımdı tek yada cok derınlıklı olsun ama hakımıyetın benım elımde oldugu ve dosya dıılde tablo kullanan bır algorıtmanın mantıgı nasıl olabılır?

    Yanı demek ıstedıgım bı tablo olsun orda ben butun kategorılerı ve alt kategorılerı tanımlayayım.. Sonra da kayıt gırmek ısteyen adama aha kategorıler bunlar bunlar sec secmıyosan kendın gır yok degıstırmek ıstıyosan buyur degıstır dıyebılmek..

    Nasıl olur bu tablo olayı.. Mesela alan adı ana kategorıyı temsıl etse ve o alan adındakı tum kayıtlar alanın alt kategorılerı olsa olurmu?
     
  6. mkarabulut

    mkarabulut Misafir

    Öncelikle veritabanı kullanma konusunda anlaştık sanırım... :)

    Şöyle diyelim, sadece bi kategoriler tablosu senin işini görür ama performans açısından bu adamların yaptığı daha iyidir, sebebi ise uygulamalarında recursive bi şeylere çokca başvurdukları için normalizasyon işlemini ona göre yapmışlar sanırım,tabi bir de 1-many değilde,many-many ilişkiler var olabilir kategoriler arasında ,neyse bunu en sonda açıklarım...

    Tek bi tablo işini görür demiştim, kategoriler tablosu

    kategori_id auto_increment
    ust_kategori_id INT default '0'
    kategori_isim varchar(50)

    Bunlar tmel olan 3 alan,tabi ihtiyaçlarına göre başka alanlarda ekleyebilirsin.

    Mesela tüm kategorileri alt kategorilerde dahil,altalta listeleme işlemi yapan scriptin şöyle bi şeyler olabilir :
    <?
    function find_subcats($id,$depth){
    $query=mysql_query("SELECT kategori_id,kategori_isim FROM kategoriler WHERE ust_kategori_id=$id");
    if (mysql_num_rows($query)>0){
    $depth++;
    while ($row=mysql_fetch_row){
    for ($i=0;$i<$depth;$i++) echo "+";
    echo $row[1]."<br>";
    find_subcats($row[0],$depth)
    }

    }
    ?>


    //Programın ana kısmı
    find_subcats(0,0);
    ?>

    temel olarak bu işini görür. $depth değişkenine gelince sadece alt kategorileri ana kategorilerin biraz daha içerisinde göstermek için kullandım.

    Gelelim şu iki tablo meselesine :
    Üstad dikkat ettiysen, biz recursive fonksiyonda sadece kategori_id ve kategori_isim alanlarını tablodan aldık, genelde de tabloya en çok eriştiğimiz zaman bu fonksiyonu kullandığımız zaman olacak. Yani tabloyu sadece kategori_id ve kategori_isim değişkenlerinden oluştursaydık recursive fonksiyonun performansını artırmış olacaktık.

    İkincisi bizim kategori yapımızda her alt kategorinin sadece bir tane üst kategorisi olabiliyor. Eğer her alt kategorinin birden fazla üst kategorisi olsaydı onu da ayrı bi tablo şeklinde tutmak gerekecekti :
    Kod:
    +---------------+--------------------+
    | kategori_id | ust_kategori_id | 
    +---------------+--------------------+
    |       1           |            0            | 
    +---------------+--------------------+
    |       2           |            1            | 
    +---------------+--------------------+
    |       2           |            0            | 
    +---------------+--------------------+
    
    Böylece 2 nolu kategori hem en üstte hem 1 nolu kategorinin altından erişilebilinecek, ama kategori tablosunda iki kere kayıt edilmek zorunda kalınmayacak...

    Genel olarak böyle,

    kolay gelsin
     
  7. HunTER

    HunTER ...

    Kayıt:
    15 Ağustos 2002
    Mesajlar:
    8,684
    Beğenilen Mesajlar:
    0
    Meslek:
    Web Programlama
    Şehir:
    İstanbul
    Anladım.. Eger becerebılırsem kodu buraya gonderırım
     
  8. mkarabulut

    mkarabulut Misafir

    Kolay gelsin
     
  9. LoS.ToF

    LoS.ToF Daimi Üye

    Kayıt:
    11 Ağustos 2002
    Mesajlar:
    1,088
    Beğenilen Mesajlar:
    0
    Meslek:
    PHP Developer
    Şehir:
    Antalya
    benim sana tavsiyem xml dir böy7le bir şeyde çok rahat olursun ?
     
  10. HunTER

    HunTER ...

    Kayıt:
    15 Ağustos 2002
    Mesajlar:
    8,684
    Beğenilen Mesajlar:
    0
    Meslek:
    Web Programlama
    Şehir:
    İstanbul
    Saol ama benım dusundugum baska bısey.. Elımde javayla hazırlanmıs bır tree navıgasyon scrıptı vardı.. PHP ıle bu scrıptı bırlestırdım ve ortaya baya ıyı bısey cıktı.. Sonsuz derınlıklı ve agac gorunumu java tarafından goruntulenen bısey.. Izahı bıraz zor ama mustafanın verdıgı fonksıyonu bı parca degıstırerek scrıptın ıstedıgı dızı degıskenlerını yazdırdım html ıcıne dıyebılırım.. Gerıye bıtek gırıs cıkıs zımbırtıları kaldı.. Yanı bu saatten sonra baska bı yol denemek mantıksız olur..
     
  11. LoS.ToF

    LoS.ToF Daimi Üye

    Kayıt:
    11 Ağustos 2002
    Mesajlar:
    1,088
    Beğenilen Mesajlar:
    0
    Meslek:
    PHP Developer
    Şehir:
    Antalya
    anladım... kodu bekleriz :D