PHP ile Tek Sorguda Sınırsız Alt Kategori Mantığı

NaMLu

webmaster.tc
Üye
Katılım
8 Ağu 2012
Mesajlar
153
Konum
404 - Not Found
Merhaba arkadaşlar bu mantığı bir gece üzerine düşerek buldum. Gerekli açıklamaları açıklama satırı olarak yazdım. İlk olarak kullandığım veritabanını sizlerle paylaşmak istiyorum.

SQL:

Kod:
-- phpMyAdmin SQL Dump
-- version 3.4.5
-- http://www.phpmyadmin.net
--
-- Anamakine: localhost
-- Üretim Zamanı: 10 Ağu 2012, 02:39:52
-- Sunucu sürümü: 5.5.16
-- PHP Sürümü: 5.3.8

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Veritabanı: `ders`
--

-- --------------------------------------------------------

--
-- Tablo için tablo yapısı `kategoriler`
--

CREATE TABLE IF NOT EXISTS `kategoriler` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `kategori` varchar(70) NOT NULL,
  `ustKat` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

--
-- Tablo döküm verisi `kategoriler`
--

INSERT INTO `kategoriler` (`id`, `kategori`, `ustKat`) VALUES
(1, 'Haber', 0),
(2, 'Programlama', 0),
(3, 'Teknoloji', 1),
(4, 'Siyaset', 1),
(5, 'C#', 2),
(6, 'C++', 2),
(7, 'Java', 2),
(8, 'Visual Basic', 2),
(9, 'Ornek Uygulamalar', 5);

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
Bu sizin için dışa aktardığım veritabanımdı. Şimdi PHP kodlarını vereyim.

PHP:

PHP:
<?php

// MySQL Bağlantısı
mysql_select_db("ders",mysql_connect("localhost","root",""));

// Dizi oluşturuyoruz.
$tumKategoriler = array();

// MySQL veritabanındaki tüm kategorileri oluşturduğumuz diziye ekliyoruz.
$katSorgu = mysql_query("SELECT * FROM kategoriler");
while($katYaz = mysql_fetch_object($katSorgu))
{
    $tumKategoriler[$katYaz->id]['id'] = $katYaz->id;
    $tumKategoriler[$katYaz->id]['kategori'] = $katYaz->kategori;
    $tumKategoriler[$katYaz->id]['ustKat'] = $katYaz->ustKat;
}

// Ana kategorileri almak için bir fonksiyon yazıyoruz.
function kategorileriBul($kategoriler)
{
    $dizi = array();
    
    foreach($kategoriler as $kategori)
    {
        if($kategori['ustKat'] == 0) $dizi[] = $kategori;
    }
    return $dizi;
}

// Herhangi bir kategorinin alt kategorilerini bulmak için bir fonksiyon yazıyoruz.
function altKategorileriBul($ustKat,$kategoriler,$tekrar = 2)
{
    // Bir dizi oluşturuyoruz.
    $dizi = array();
    
    // Tüm kategorileri döngüye sokuyoruz.
    foreach($kategoriler as $kategori)
    {
        // Belirtilen kategorilerin alt kategorilerini alıyoruz ve diziye ekliyoruz.
        if($kategori['ustKat'] == $ustKat)
        {
            $dizi[] = $kategori;
        }
    }
    
    // Dizide eleman var mı onu kontrol ediyoruz.
    if(count($dizi) > 0)
    {
        // Dizideki alt kategorileri döngüye sokuyoruz.
        foreach($dizi as $kat)
        {
            // Alt kategorileri yazdırıyoruz.
            echo '<option>'.str_repeat('   ',$tekrar).' '.$kat['kategori'].'</option>';
            // Yazdırılan kategorinin alt kategorilerini bulduruyoruz. Yani döngü içinde döngü oluşturarak verilerin dallanmasını sağlıyoruz.
            altKategorileriBul($kat['id'],$kategoriler,$tekrar+3);
        }
    }
}

// Ana kategorileri alıyoruz.
$anaKategoriler = kategorileriBul($tumKategoriler);

echo '<select>';
    // Ana kategorileri liste şeklinde alıyoruz.
    foreach($anaKategoriler as $kategori)
    {
        // Ana kategorileri ekrana yazdırıyoruz.
        echo '<option>'.str_repeat('   ',0).' '.$kategori['kategori'].'</option>';
        // Alt Kategorilerini dallandırarak yazdırıyoruz.
        altKategorileriBul($kategori['id'],$tumKategoriler);
    }
echo '</select>';

// MySQL Bağlantısını kapatıyoruz.
mysql_close();
?>
Şimdi de sizler için ekran görünütüsünü koyayım.



Jette Hocamın Hazırladığı:

Ekran görüntüsü:



PHP:
 <?php  
/** 
 * Sınırsız kategori fonksiyonu 
 * 
 * @author Hakan KAYA  
 * Emeğe saygı ... 
 */ 

header('Content-Type:Text/html; charset=utf8 '); 

// Dbden aldığınız menü veya sayfalar. 
$sayfalar = array( 
            array( 
                'id' =>1 ,  
                'menu' => 'Anasayfa', 
                'ebeveyn' => 0 
            ) 
            , 
            array( 
                'id' =>2 ,  
                'menu' => 'Hakkımızda', 
                'ebeveyn' => 0 
            ) 
            , 
            array( 
                'id' =>3 ,  
                'menu' => 'İletişim', 
                'ebeveyn' => 0 
            ) 
            , 
            array( 
                'id' =>4 ,  
                'menu' => 'Biz Kimiz', 
                'ebeveyn' => 2 
            ) 
            , 
            array( 
                'id' =>5 ,  
                'menu' => 'Misyonumuz', 
                'ebeveyn' => 4 
            ) 
            , 
            array( 
                'id' =>6 ,  
                'menu' => 'Vizyonumuz', 
                'ebeveyn' => 4 
            ) 
); 




// Fonksyionumuz 
function sayfa_nested($sayfalar , $ebeveyn = 0  , $kademe_pixel = 5 ,  $i = 0  ,  $menuler = NULL , $nested = FALSE ) 
{ 

   // Sayfalar Boşşa boş döndür. 
   if(empty($sayfalar)) 
        return; 
         
         
    // Eğer fonksiyon içinden çağırılmıyorsa 
    if (!$nested) 
    { 
        // Sayfaları ebeveyn idsi ile yeni dizi oluştur 
        foreach($sayfalar as $row): 
            $items[$row['ebeveyn']][] = $row; 
        endforeach; 
    } 
    else 
    { 
        // Nested ise gelen sayfaları al 
        $items  = $sayfalar; 
    } 

    // Gelen sayfaları aç 
    foreach($items[$ebeveyn] as $sayfa) 
    { 
        // Boşluk hesapla 
        $bosluk = str_repeat(' ',($i*$kademe_pixel)); 
         
        // Menuleri değişkene aktar 
        $menuler    .= '<option value="'.$sayfa['id'].'">'.$bosluk.$sayfa['menu'].'</option>'.PHP_EOL; 
         
        // Açılan menude bir alt sayfa var ise nested çağır 
        if (isset($items[$sayfa['id']])) 
            $menuler = sayfa_nested($items , $sayfa['id']  , $kademe_pixel , ($i+1) , $menuler , TRUE); 

    } 

    // Oluşan menüleri return et 
    return $menuler; 
} 


echo '<select>'; 
echo sayfa_nested($sayfalar); 
echo '</select>';
 

Ekli dosyalar

  • 3.6 KB Görüntüleme: 217

ByAkman

webmaster.tc
Üye
Katılım
6 Ağu 2012
Mesajlar
391
Konum
in the PHP
Tuttum bu dersi usta arkadaşlara lazım olur en fazla kafa yorulan olaylardan
 

kralmermi

webmaster.tc
Üye
Katılım
6 Ağu 2012
Mesajlar
93
Konum
<?php ?>
Tebrik ederim. aynı şekilde veritabanı kullanıyoruz ancak hiç bu şekilde yazmayi denememiştim. Hatta dün bi iş geldi nasil yaparim diye düşünüyordum. gayet hoş olmuş.
 

NaMLu

webmaster.tc
Üye
Katılım
8 Ağu 2012
Mesajlar
153
Konum
404 - Not Found
  • Konu Sahibi Konu Sahibi
  • #4
Tuttum bu dersi usta arkadaşlara lazım olur en fazla kafa yorulan olaylardan
Tebrik ederim. aynı şekilde veritabanı kullanıyoruz ancak hiç bu şekilde yazmayi denememiştim. Hatta dün bi iş geldi nasil yaparim diye düşünüyordum. gayet hoş olmuş.
Yorumlarınız için teşekkür ederim arkadaşlar. Bunu bulmak için 2 - 3 saat kafa patlattım. Başkaları bu kadar yorulmasın diye burada paylaştım. İnşallah daha fazla kişinin işine yarar.
 

jette

webmaster.tc
Üye
Katılım
6 Ağu 2012
Mesajlar
21
Konum
Ümraniye
Aynısını bu akşama inşallah tek fonksiyon ve daha basit şekilde yazıp verecem .
 

NaMLu

webmaster.tc
Üye
Katılım
8 Ağu 2012
Mesajlar
153
Konum
404 - Not Found
  • Konu Sahibi Konu Sahibi
  • #7
Aynısını bu akşama inşallah tek fonksiyon ve daha basit şekilde yazıp verecem .
Ben o şekilde düşünüyordum ancak şöyle bir durum var. Alt kategorilerinde altını alabilmek için fonksiyon içinde fonksiyon kullanmak gerekiyor. Ama siz farklı bir yöntem biliyorsanız çok güzel olur :) Biz de yeni bir şeyler öğrenmiş oluruz :)

paylaşım için teşekkürler.
Rica ederim
 

jette

webmaster.tc
Üye
Katılım
6 Ağu 2012
Mesajlar
21
Konum
Ümraniye
Öncelikle söz verdiğim gibi fonksiyonu yazdım.
Açıklama satırları mevcut zaten basit bir yapısı var ama gayet hızlı ve sadedir.
Ben basit tarzını yazdım çok daha geliştirilebilir ek özellikler katılabilir.

Dosya olarakta paylaşıyorum ekte localde denersiniz.
Şifresi : webmaster.tc

Görüntü:





PHP:
<?php 
/**
 * Sınırsız kategori fonksiyonu
 *
 * @author Hakan KAYA 
 * Emeğe saygı ...
 */

header('Content-Type:Text/html; charset=utf8 ');

// Dbden aldığınız menü veya sayfalar.
$sayfalar = array(
			array(
				'id' =>1 , 
				'menu' => 'Anasayfa',
				'ebeveyn' => 0
			)
			,
			array(
				'id' =>2 , 
				'menu' => 'Hakkımızda',
				'ebeveyn' => 0
			)
			,
			array(
				'id' =>3 , 
				'menu' => 'İletişim',
				'ebeveyn' => 0
			)
			,
			array(
				'id' =>4 , 
				'menu' => 'Biz Kimiz',
				'ebeveyn' => 2
			)
			,
			array(
				'id' =>5 , 
				'menu' => 'Misyonumuz',
				'ebeveyn' => 4
			)
			,
			array(
				'id' =>6 , 
				'menu' => 'Vizyonumuz',
				'ebeveyn' => 4
			)
);




// Fonksyionumuz
function sayfa_nested($sayfalar , $ebeveyn = 0  , $kademe_pixel = 5 ,  $i = 0  ,  $menuler = NULL , $nested = FALSE )
{

   // Sayfalar Boşşa boş döndür.
   if(empty($sayfalar))
		return;
		
		
	// Eğer fonksiyon içinden çağırılmıyorsa
	if (!$nested)
	{
		// Sayfaları ebeveyn idsi ile yeni dizi oluştur
		foreach($sayfalar as $row):
			$items[$row['ebeveyn']][] = $row;
		endforeach;
	}
	else
	{
		// Nested ise gelen sayfaları al
		$items  = $sayfalar;
	}

	// Gelen sayfaları aç
	foreach($items[$ebeveyn] as $sayfa)
	{
		// Boşluk hesapla
		$bosluk = str_repeat(' ',($i*$kademe_pixel));
		
		// Menuleri değişkene aktar
		$menuler	.= '<option value="'.$sayfa['id'].'">'.$bosluk.$sayfa['menu'].'</option>'.PHP_EOL;
		
		// Açılan menude bir alt sayfa var ise nested çağır
		if (isset($items[$sayfa['id']]))
			$menuler = sayfa_nested($items , $sayfa['id']  , $kademe_pixel , ($i+1) , $menuler , TRUE);

	}

	// Oluşan menüleri return et
	return $menuler;
}


echo '<select>';
echo sayfa_nested($sayfalar);
echo '</select>';
 

Ekli dosyalar

NaMLu

webmaster.tc
Üye
Katılım
8 Ağu 2012
Mesajlar
153
Konum
404 - Not Found
jette hocam ellerine sağlık :) Gayet güzel ve temiz bir iş olmuş :) Kodlarını ana konuya ekledim :)
 

jette

webmaster.tc
Üye
Katılım
6 Ağu 2012
Mesajlar
21
Konum
Ümraniye
Emeklerinize sağlık Güzel çalışma olmuş.
jette hocam ellerine sağlık :) Gayet güzel ve temiz bir iş olmuş :)
ne yani bende tek satırdamı bitireyim işi ? :) elleriniz dert görmesin...
Ben teşekkür ederim sizlere arkadaşlar.

Hala Günümüzde Alt menu / sayfa bulmak için Db ye sorgu gönderen yazılımcılar olduğunu düşünürsek bu fonksyion onlar için altın :D
 

bashque

webmaster.tc
Üye
Katılım
10 Ağu 2012
Mesajlar
34
müsait olduğumda ben daha kullanışlısını yollarım hatta drag drop şeklinde html5 ilede yapabilirim ama buna söz vermiyorum zaman olayı
Bu arada güzel bir örnek
 

maximus28

webmaster.tc
Üye
Katılım
27 Ara 2012
Mesajlar
2
Merhaba arkadaşlar bu mantığı bir gece üzerine düşerek buldum. Gerekli açıklamaları açıklama satırı olarak yazdım. İlk olarak kullandığım veritabanını sizlerle paylaşmak istiyorum.

SQL:

Kod:
-- phpMyAdmin SQL Dump
-- version 3.4.5
-- http://www.phpmyadmin.net
--
-- Anamakine: localhost
-- Üretim Zamanı: 10 Ağu 2012, 02:39:52
-- Sunucu sürümü: 5.5.16
-- PHP Sürümü: 5.3.8

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Veritabanı: `ders`
--

-- --------------------------------------------------------

--
-- Tablo için tablo yapısı `kategoriler`
--

CREATE TABLE IF NOT EXISTS `kategoriler` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `kategori` varchar(70) NOT NULL,
  `ustKat` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

--
-- Tablo döküm verisi `kategoriler`
--

INSERT INTO `kategoriler` (`id`, `kategori`, `ustKat`) VALUES
(1, 'Haber', 0),
(2, 'Programlama', 0),
(3, 'Teknoloji', 1),
(4, 'Siyaset', 1),
(5, 'C#', 2),
(6, 'C++', 2),
(7, 'Java', 2),
(8, 'Visual Basic', 2),
(9, 'Ornek Uygulamalar', 5);

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
Bu sizin için dışa aktardığım veritabanımdı. Şimdi PHP kodlarını vereyim.

PHP:

PHP:
<?php

// MySQL Bağlantısı
mysql_select_db("ders",mysql_connect("localhost","root",""));

// Dizi oluşturuyoruz.
$tumKategoriler = array();

// MySQL veritabanındaki tüm kategorileri oluşturduğumuz diziye ekliyoruz.
$katSorgu = mysql_query("SELECT * FROM kategoriler");
while($katYaz = mysql_fetch_object($katSorgu))
{
    $tumKategoriler[$katYaz->id]['id'] = $katYaz->id;
    $tumKategoriler[$katYaz->id]['kategori'] = $katYaz->kategori;
    $tumKategoriler[$katYaz->id]['ustKat'] = $katYaz->ustKat;
}

// Ana kategorileri almak için bir fonksiyon yazıyoruz.
function kategorileriBul($kategoriler)
{
    $dizi = array();
    
    foreach($kategoriler as $kategori)
    {
        if($kategori['ustKat'] == 0) $dizi[] = $kategori;
    }
    return $dizi;
}

// Herhangi bir kategorinin alt kategorilerini bulmak için bir fonksiyon yazıyoruz.
function altKategorileriBul($ustKat,$kategoriler,$tekrar = 2)
{
    // Bir dizi oluşturuyoruz.
    $dizi = array();
    
    // Tüm kategorileri döngüye sokuyoruz.
    foreach($kategoriler as $kategori)
    {
        // Belirtilen kategorilerin alt kategorilerini alıyoruz ve diziye ekliyoruz.
        if($kategori['ustKat'] == $ustKat)
        {
            $dizi[] = $kategori;
        }
    }
    
    // Dizide eleman var mı onu kontrol ediyoruz.
    if(count($dizi) > 0)
    {
        // Dizideki alt kategorileri döngüye sokuyoruz.
        foreach($dizi as $kat)
        {
            // Alt kategorileri yazdırıyoruz.
            echo '<option>'.str_repeat('   ',$tekrar).' '.$kat['kategori'].'</option>';
            // Yazdırılan kategorinin alt kategorilerini bulduruyoruz. Yani döngü içinde döngü oluşturarak verilerin dallanmasını sağlıyoruz.
            altKategorileriBul($kat['id'],$kategoriler,$tekrar+3);
        }
    }
}

// Ana kategorileri alıyoruz.
$anaKategoriler = kategorileriBul($tumKategoriler);

echo '<select>';
    // Ana kategorileri liste şeklinde alıyoruz.
    foreach($anaKategoriler as $kategori)
    {
        // Ana kategorileri ekrana yazdırıyoruz.
        echo '<option>'.str_repeat('   ',0).' '.$kategori['kategori'].'</option>';
        // Alt Kategorilerini dallandırarak yazdırıyoruz.
        altKategorileriBul($kategori['id'],$tumKategoriler);
    }
echo '</select>';

// MySQL Bağlantısını kapatıyoruz.
mysql_close();
?>
Şimdi de sizler için ekran görünütüsünü koyayım.



Jette Hocamın Hazırladığı:

Ekran görüntüsü:



PHP:
 <?php  
/** 
 * Sınırsız kategori fonksiyonu 
 * 
 * @author Hakan KAYA  
 * Emeğe saygı ... 
 */ 

header('Content-Type:Text/html; charset=utf8 '); 

// Dbden aldığınız menü veya sayfalar. 
$sayfalar = array( 
            array( 
                'id' =>1 ,  
                'menu' => 'Anasayfa', 
                'ebeveyn' => 0 
            ) 
            , 
            array( 
                'id' =>2 ,  
                'menu' => 'Hakkımızda', 
                'ebeveyn' => 0 
            ) 
            , 
            array( 
                'id' =>3 ,  
                'menu' => 'İletişim', 
                'ebeveyn' => 0 
            ) 
            , 
            array( 
                'id' =>4 ,  
                'menu' => 'Biz Kimiz', 
                'ebeveyn' => 2 
            ) 
            , 
            array( 
                'id' =>5 ,  
                'menu' => 'Misyonumuz', 
                'ebeveyn' => 4 
            ) 
            , 
            array( 
                'id' =>6 ,  
                'menu' => 'Vizyonumuz', 
                'ebeveyn' => 4 
            ) 
); 




// Fonksyionumuz 
function sayfa_nested($sayfalar , $ebeveyn = 0  , $kademe_pixel = 5 ,  $i = 0  ,  $menuler = NULL , $nested = FALSE ) 
{ 

   // Sayfalar Boşşa boş döndür. 
   if(empty($sayfalar)) 
        return; 
         
         
    // Eğer fonksiyon içinden çağırılmıyorsa 
    if (!$nested) 
    { 
        // Sayfaları ebeveyn idsi ile yeni dizi oluştur 
        foreach($sayfalar as $row): 
            $items[$row['ebeveyn']][] = $row; 
        endforeach; 
    } 
    else 
    { 
        // Nested ise gelen sayfaları al 
        $items  = $sayfalar; 
    } 

    // Gelen sayfaları aç 
    foreach($items[$ebeveyn] as $sayfa) 
    { 
        // Boşluk hesapla 
        $bosluk = str_repeat(' ',($i*$kademe_pixel)); 
         
        // Menuleri değişkene aktar 
        $menuler    .= '<option value="'.$sayfa['id'].'">'.$bosluk.$sayfa['menu'].'</option>'.PHP_EOL; 
         
        // Açılan menude bir alt sayfa var ise nested çağır 
        if (isset($items[$sayfa['id']])) 
            $menuler = sayfa_nested($items , $sayfa['id']  , $kademe_pixel , ($i+1) , $menuler , TRUE); 

    } 

    // Oluşan menüleri return et 
    return $menuler; 
} 


echo '<select>'; 
echo sayfa_nested($sayfalar); 
echo '</select>';
Böyle bişey arıyordum sağol
 

Üst