Yazdır 13 Ocak 2011 Perşembe (Hit: 63469)

Sayfalama

Veritabanından okunup listelenen kayıtların sayısı çok fazla olduğu zaman bu kayıtlar sayfalanarak listelenir. Aksi halde tüm kayıtları web sayfasında göstermek hem sayfanın yüklenme süresi uzatır hem de kullanıcılar için pek kullanışlı olmaz.

Bu yazımızda bir tablodaki kayıtları nasıl sayfalayacağımızı anlatmaya çalışacağız. Unutmayınız farklı sayfalama algoritmaları olabilir. Biz de kendi algoritmamızı kullanarak sayfalama yapmaya çalışacağız.

Öncelikle okul isimli veritabanına bağlanalım. (baglan.php)

<?php
// bu sayfa baglan.php sayfasıdır.
$sunucu="localhost";
$kullanici="root";
$sifre="1234";
$veritabani="okul";

if (@!mysql_connect($sunucu, $kullanici, $sifre)){
	$mesaj="Veritabanı bağlantısı yapılamadı!<br>";
	$mesaj.="Hata açıklaması: ".mysql_error();
	die($mesaj);
}

if(@!mysql_select_db($veritabani)){
	$mesaj="$veritabani veritabanı seçilemedi!<br>";
	$mesaj.="Hata açıklaması: ".mysql_error();
	die($mesaj);
}
?>

Örneğimizde veritabanında öğrenciler tablosundaki tüm öğrencileri kayıt sayısı az olduğu için beşer beşer sayfalayacağız.

Sayfalama yaparken aslında öğrenciler tablosundaki 5 kaydı alıp gösteriyoruz. Hangi 5 kaydı göstereceğimizi limit ve offset ifadelerini kullanarak bulacağız. Limit, sınır anlamına gelmektedir. Kaç tane kayıt listelensin sorusunun cevabı limittir. Offset, ise kayma anlamına gelmektedir. İlk kayıttan itibaren ne kadar kayıt sonra listelenmeye başlansın sorusunun cevabı da offsettir. Aşağıdaki tabloyu dikkatle inceleyiniz.

Kayıtlar Sayfa Limit Offset
1 ile 5 arasındaki kayıtlar için: 1 5 0
6 ile 10 arasındaki kayıtlar için: 2 5 5
11 ile 15 arasındaki kayıtlar için: 3 5 10
16 ile 20 arasındaki kayıtlar için: 4 5 15
... ... ... ...

Şimdi bu tabloda ileride kullanmak üzere değişkenler arasındaki ilişkileri bulalım.

$limit=5; // sayfalanacak kayıt sayısı
$offset=($sayfa-1)*$limit; // kayma

Bu bilgiler ışığında istediğimiz herhangi bir sayfayı listeleyelim isterseniz.

<!-- bu sayfa index.php sayfasıdır. -->
<html>
    <head>
        <title>Öğrenci Listesi</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
		<table border="1" cellspacing="2" cellpadding="2">
		  <tr class="baslik">
		    <th colspan="6" align="center">Öğrenciler Tablosu</th>
	      </tr>
		  <tr>
		    <th>S.n.</th>
		    <th>Numarası</th>
		    <th>Adı</th>
		    <th>Soyadı</th>
		    <th>Cinsiyeti</th>
		    <th>Sınıfı</th>
	      </tr>
		  <?php
		  include("baglan.php");
		  $sayfa=2; // listelenecek sayfa numarası
		  $limit=5; // listelenecek kayıt sayısı
		  $offset=($sayfa-1)*$limit;
		  $i=$offset; // sıra no için kullanılacak
		  mysql_query("set names utf8");
		  $sonuc=mysql_query("select * from ogrenciler limit $limit offset $offset;");
		  while($kayit=mysql_fetch_array($sonuc)){
			  echo "<tr>";
			  echo "<th align=\"right\">",++$i,"</th>";
			  echo "<td align=\"right\">",$kayit["ogrenci_no"],"</td>";
			  echo "<td>",$kayit["adi"],"</td>";
			  echo "<td>",$kayit["soyadi"],"</td>";
			  echo "<td>",$kayit["cinsiyeti"],"</td>";
			  echo "<td>",$kayit["sinif_kodu"],"</td>";
			  echo "</tr>";
		  }
        ?>
    </table>
    <?php echo "<h3>Sayfa: $sayfa</h3>"; ?>
    </body>
</html>
$sonuc=mysql_query("select * from ogrenciler limit $limit offset $offset;");

Burada SQL sorgusunu dikkat ediniz. limit ve offset deyimleri sırasıyla listelenecek kayıt sayısını ve ilk kayıttan itibaren kayma sayısını ifade etmektedir.

Not: Önce limit deyimini, sonra offset deyimini kullanmaya dikkat ediniz. Bu sorguya benzer birkaç örnek daha verelim.

 

Örnek 1: Öğrenciler tablosunun 20 kayıtlık olan sayfalarından 3. sayfasını listeleyen SQL komutunu yazalım.

Limit=20, Offset=(3-1)*20=40

Select * from ogrenciler limit 20 offset 40;

Aynı sorgu kısaca şu şekilde de yazılabilir.

Select * from ogrenciler limit 20, 40;

 

Örnek 2: Mesajlar tablosunun 30 kayıtlık olan sayfalarından 4. sayfasını listeleyen SQL komutunu yazalım.

Limit=30, Offset=(4-1)*30=90

Select * from mesajlar limit 30 offset 90;
/* yada */
Select * from mesajlar limit 30, 90;

 

Örnek 3: İletiler tablosundaki iletileri tarihe göre azalan sıralayıp 15 kayıtlık olan sayfalarından 5. sayfasını listeleyen SQL komutunu yazalım.

Limit=15, Offset=(5-1)*15=60

select * from iletiler order by tarih desc limit 15 offset 60;
/* yada */
select * from iletiler order by tarih desc limit 15, 60;

 

Örnek 4: Bu örneğimizde iki tabloyu birleştirelim. Öğrenciler ve notlar tablosunu kullanarak notu 45 ve üzeri olan öğrencilerin sadece numarasını, adını, soyadını ve dersin kodunu gösterelim. Öğrenciler adlarına göre artan sıralanmış olsun. Listelenecek olan sayfa ise 5 kişilik olan 3.sayfa olsun.

Limit=5, Offset=(3-1)*5=10

Select ogrenciler.ogrenci_no, ogrenciler.adi, ogrenciler.soyadi, notlar.ders_kodu from ogrenciler, notlar
where ogrenciler.ogrenci_no=notlar.ogrenci_no and notlar.notu>=45
order by ogrenciler.adi asc limit 5 offset 10;

/* yada */

Select ogrenciler.ogrenci_no, ogrenciler.adi, ogrenciler.soyadi, notlar.ders_kodu from ogrenciler, notlar
where ogrenciler.ogrenci_no=notlar.ogrenci_no and notlar.notu>=45
order by ogrenciler.adi asc limit 5, 10;

 

Şimdi bu ön bilgilendirmeden sonra örneğimizi tam olarak yapmaya çalışalım. Bu tam örneğimizde aşağıdaki durumlara dikkat etmemiz gerekmektedir.

  • Öncelikle toplam kayıt sayısı ve buna karşılık gelen sayfa sayısı bulunacak
  • Sayfa ilk kez açıldığında (get olayı yoksa) ilk sayfa gösterilecek. (limit 5 offset 0)
  • Kullanıcı ilk sayfa linkine tıklarsa (get ile gelen sayfa no 1 ise) ilk sayfa gösterilecek. (limit 5 offset 0)
  • Kullanıcı son sayfa linkine tıklarsa (get ile gelen sayfa no toplam sayfa sayısı ise) son sayfa gösterilecek (limit 5 offset (toplam_sayfa-1)*5)
  • Kullanıcı sayfa isteğinde bulunursa (get ile gelen sayfa no varsa) offset hesaplanacak (limit 5 offset hesaplanacak)
  • Kullanıcı önceki sayfa linkine tıklarsa listelenen mevcut sayfa numarasının 1 eksiği get ile gönderilecek ve o sayfa listelenecek
  • Kullanıcı sonraki sayfa linkine tıklarsa listelenen mevcut sayfa numarasının 1 fazlası get ile gönderilecek ve o sayfa listelenecek
  • Son olarak ilk sayfa listelenmiş ise ilk sayfa ve önceki sayfa linkleri gösterilmeyecek. Aynı şekilde son sayfa listelenmiş ise sonraki ve son sayfa linkleri de gösterilmeyecek.
<!-- bu sayfa index.php sayfasıdır. -->
<html>
    <head>
        <title>Öğrenci Listesi</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
		<table border="1" cellspacing="2" cellpadding="2">
		  <tr class="baslik">
		    <th colspan="6" align="center">Öğrenciler Tablosu</th>
	      </tr>
		  <tr>
		    <th>S.n.</th>
		    <th>Numarası</th>
		    <th>Adı</th>
		    <th>Soyadı</th>
		    <th>Cinsiyeti</th>
		    <th>Sınıfı</th>
	      </tr>
		  <?php
		  include("baglan.php");
		  $limit=5;
		  //------------TOPLAM KAYIT VE SAYFA SAYISI BULUNUYOR----- 
		  $sonuc=mysql_query("select count(*) as sayi from ogrenciler;");
		  $kayit=mysql_fetch_array($sonuc);
		  $kayit_sayisi=$kayit["sayi"];
		  $sayfa_sayisi=ceil($kayit_sayisi/$limit);
		  
		  //-------------SAYFA NUMARASI BULUNUYOR----------------		  
		  if(!$_GET) // GET olayı yoksa sayfa ilk kez açıldıysa
			$sayfa=1;
		  else{      // GET olayı varsa yani sayfa isteği geldiyse
			$sayfa=$_GET["sayfa"];
		  }
		  $offset=($sayfa-1)*$limit;
		  $i=$offset; // sıra no için kullanılıyor
		  mysql_query("set names utf8");
		  $sonuc=mysql_query("select * from ogrenciler limit $limit offset $offset;");
		  while($kayit=mysql_fetch_array($sonuc)){
			  echo "<tr>";
			  echo "<th align=\"right\">",++$i,"</th>";
			  echo "<td align=\"right\">",$kayit["ogrenci_no"],"</td>";
			  echo "<td>",$kayit["adi"],"</td>";
			  echo "<td>",$kayit["soyadi"],"</td>";
			  echo "<td>",$kayit["cinsiyeti"],"</td>";
			  echo "<td>",$kayit["sinif_kodu"],"</td>";
			  echo "</tr>";
		  }
        ?>
    </table>
	<?php
	//------------TABLONUN ALTINDAKİ SAYFALAMA LİNKLERİ OLUŞTURULUYOR------
	echo "<h3>Sayfa: $sayfa</h3>";
	echo "<p>";
	if($sayfa!=1){ // İlk Sayfa ve Önceki Sayfa linkleri oluşturuluyor 
		echo "<a href=\"index.php?sayfa=1\">İlk Sayfa</a> ";
		$onceki_sayfa=$sayfa-1;
		echo "<a href=\"index.php?sayfa=$onceki_sayfa\">Önceki Sayfa</a> ";
	}
	for($i=1; $i<=$sayfa_sayisi; $i++){ // sayfa numarası linkleri oluşturuluyor
		echo "<a href=\"index.php?sayfa=$i\">$i</a> ";
	}
	if($sayfa!=$sayfa_sayisi){ // Sonraki Sayfa ve Son Sayfa linkleri oluşturuluyor
		$sonraki_sayfa=$sayfa+1;
		echo "<a href=\"index.php?sayfa=$sonraki_sayfa\">Sonraki Sayfa</a> ";
		echo "<a href=\"index.php?sayfa=$sayfa_sayisi\">Son Sayfa</a> ";
	}

	echo "</p>";
	?>
    </body>
</html>

Bu örneğimizde sade olması açısından herhangi bir biçimlendirme yapılmamıştır. Buradaki tablo, satırlar, metinler ve sayfa numaraları CSS ile biçimlendirilebilir. Hatta İlk, Önceki, Sonraki ve Son sayfa yazılarının yerine resimler de konulabilir. Listelenen sayfa numarasına karşılık gelen sayı yani bulunulan sayfanın numarası yine CSS ile biçimlendirilebilir. Bunun için for döngüsü şu şekilde kurulabilir.

for($i=1; $i<=$sayfa_sayisi; $i++){ // sayfa numarası linkleri oluşturuluyor
	echo "<a href=\"index.php?sayfa=$i\"".(($i==$sayfa)?" class=\"secili\"":"").">$i</a> ";
}

Görüldüğü gibi seçili olan sayfanın linkine class="secili" ifadesi ekleniyor. Sonra secili sınıfının CSS biçimi istenilen şekilde yazılabilir. Örneğin aşağıdaki gibi tanımlanabilir.

.secili{
	font-weight:bold;
	border:#333 1px solid;
	padding:1px;
	background-color:#ECF;
}

Umarım sayfalama konusu hakkında aklınızda yeni fikirler oluşturmuşuzdur. Kolay gelsin.


Bu site meslek liselerinde bilişim bölümü web programcılığı dalında okutulan internet programcılığı dersine yardımcı olması için tasarlanmıştır. İletişim için iletisim@phpdefteri.com
Apache PHP MySQL PhpMyAdmin EasyPHP Xampp AppServ Wamp W3School

www.phpdefteri.com © 2010