Veritabanından çekilen içerikleri PHP ile sayfalamak

kendi yazdığınız bir içerik paylaşım sisteminde; içerikleriniz, veri tabanından çekildiğinde artık eskisi gibi tek bir sayfaya sığmıyorsa, sayfalama zamanı gelmiş demektir. bu sorunu çözebilmemiz adına veri tabanından çekilen içerikleri PHP* ile sayfalama işlemi yapacağız.

*aslında bu mantık ile bir çok dilde ve ya başka kaynaklardan gelen (xml, array vb.) bilgilerle sayfalama işlemini yapabilirsiniz.

1. Toplam sayfa sayısını bulmak

sayfalama işlemine, toplam kaç sayfa üretmemiz gerektiğini bularak başlayalım. burada kullanacağımız mantığın ana gereksinimi bir sayfada kaç adet içerik göstermek istediğimiz. toplam içerik sayımızı, bir sayfada göstermek istediğimiz içerik sayısına böldüğümüzde toplam sayfa sayısını bulmuş oluyoruz:

$sayfada= 5; //bir sayfada gösterilecek içerik sayısını belirtiyoruz.
 
$sorgu= mysql_query('SELECT COUNT(*) AS toplam FROM mesajlar');
$sonuc = mysql_fetch_assoc($sorgu);
$toplam_icerik = $sonuc['toplam'];
 
$toplam_sayfa = ceil($toplam_icerik / $sayfada);

 

burada önemli olan bölüm sonucunu yuvarlamak. örneğin; toplam içerik sayımız 12 ve her sayfada 5 içerik göstermek istediğimizde (12/5) sonuç 2.4 çıkacaktı. biz bu sonucu ceil komutu ile 3‘e yuvarladık. eğer ceil yerine round fonksiyonunu kullansaydık 2‘ye yuvarlayacaktı. bu durumda son 2 içeriğimiz gözükmeyecekti.

2. Sayfa içeriğini listelemek

toplam sayfa sayımızı bulduk. şimdi, sayfaya göre içerik listeleme işlemi yapacağız. bu noktada kullanıcı tarafından sayfa numarasını almamız gerekiyor. örnekte sayfa numarası verisi GET ile çekiliyor. yani, sayfa numarası verisi 2 ise; adres çubuğunda index.php?sayfa=2 gözükecek.

//eğer sayfa numarası girilmemişse 1 varsayılacak.
$sayfa = isset($_GET['sayfa']) ? (int) $_GET['sayfa'] : 1;
 
//eğer 1'den küçük bir sayfa sayısı girildiyse yine 1 varsayılacak.
if($sayfa < 1) $sayfa = 1; 
 
//eğer sayı, toplam sayfamızdan fazla yazılırsa onu en son sayfa numarası varsayalım.
if($sayfa > $toplam_sayfa) $sayfa = $toplam_sayfa;

 

bize kullanıcıdan sayfa numarası verisi lazım olduğundan sayı haricinde yapacağı klavye girişlerini engellememiz lazım. bunu yapabilmek için kod menüsündeki 2. satırda (int) kullandık.

Hangi sayfada olduğumuzu da belirlediğimize göre artık bulunduğumuz sayfanın içeriklerini veri tabanından çekebiliriz:

// kaçıncı içerikten başlanacağını ifade edecek limit değeri.
$limit = ($sayfa - 1) * $sayfada;
 
$sorgu = mysql_query('SELECT * FROM mesajlar LIMIT ' . $limit . ', ' . $sayfada);
 
while($icerik = mysql_fetch_assoc($sorgu)) {
   // ...
}

 

Sanırım kilit ve kafa karıştıran noktası burası. LIMIT ifadesi ile tüm içerikler arasından bizim istediğimiz adet ve aralıktaki içerikleri istiyoruz. Normalde sadece “LIMIT 10” dediğimizde 10 adet içerik verir. Fakat virgül ile ikinci bir sayı daha girdiğimizde kaçıncı sıradan sonra vereceğini ifade eder. Yani “LIMIT 0, 5” dediğimizde 0. içerikten yani ilk içerikten sonra 5 tane ver diyoruz, bu bizim ilk sayfamız oluyor. 2. sayfa için “LIMIT 5, 5” yani 5. içerikten sonra 5 tane göster diyoruz. 3. sayfa için “LIMIT 10, 5”. Bu ifade için “($sayfa – 1) * $sayfada” işlemimizi yapıyoruz.

3. Sayfa numaralarını göstermek

sırasıyla, toplam sayfa sayımızı ve sayfalarda gösterilecek içerikleri belirledik. şimdi ise her en alta, sayfalarımızın numaraları ile birlikte o numaralı sayfaya (örneğin 5’e tıklandığında 5 numaralı sayfaya gidecek.) gitmesini sağlayacak linkleri oluşturacağız:

for($s = 1; $s <= $toplam_sayfa; $s++) {
   if($sayfa == $s) { //eğer bulunduğumuz sayfa ise link yapma.
      echo $s . ' '; 
   } else {
      echo '<a href="?sayfa=' . $s . '">' . $s . '</a> ';
   }
}

 

kod menüsünün 2. satırında bulunduğumuz sayfayı da dikkate alarak o sayfayı yazarken link yapmadık.

Kod Ekranı

şimdi ise rahat anlayabilmemiz için kod ekranımıza bir bütün olarak bakalım:

$sayfada = 5; // sayfada gösterilecek içerik miktarını belirtiyoruz.
 
$sorgu = mysql_query('SELECT COUNT(*) AS toplam FROM mesajlar');
$sonuc = mysql_fetch_assoc($sorgu);
$toplam_icerik = $sonuc['toplam'];
 
$toplam_sayfa = ceil($toplam_icerik / $sayfada);
 
$sayfa = isset($_GET['sayfa']) ? (int) $_GET['sayfa'] : 1;
 
if($sayfa < 1) $sayfa = 1; 
if($sayfa > $toplam_sayfa) $sayfa = $toplam_sayfa; 
 
$limit = ($sayfa - 1) * $sayfada;
$sorgu = mysql_query('SELECT * FROM mesajlar LIMIT ' . $limit . ', ' . $sayfada);
 
while($icerik = mysql_fetch_assoc($sorgu)) {
   // ...
}
 
for($s = 1; $s <= $toplam_sayfa; $s++) {
   if($sayfa == $s) { // eğer bulunduğumuz sayfa ise link yapma.
      echo $s . ' '; 
   } else {
      echo '<a href="?sayfa=' . $s . '">' . $s . '</a> ';
   }
}

 

Ek olarak;

yukarıda anlatılan bu yöntemle artık içeriklerimizi sayfalara bölebiliriz. yapabilirsiniz. ancak, elimizde çok fazla içerik ve bu nedenle yüzlerce sayfamız varsa; 1’den 200’lere kadar çok uzun sayfalar bağlantımız olur. hem çirkin hem de kullanıcı dostu olmayan bir durumla karşı karşıya kalırız. bunu önlemek için; ne kadar çok sayfamız olursa olsun, kullanıcı o an kaçıncı sayfada ise ona ilaveten sonraki ve önceki 5-10 sayfayı göstermeliyiz. yani şu şekilde;

<<İlk sayfa <Önceki 35 36 37 38 [39] 40 41 42 43 Sonraki> Son sayfa>>

 

bu görüntü için gerekli olan kod bloğu aşağıda. aşağıdaki kod bloğu istenildiği gibi düzenlenip, kullanılabilir. dikkat edilmesi gereken nokta; bu yöntemin doğru ve güzel çalışması için $sayfa_goster değerine her zaman tek sayı girilmesi gerektiği.

// yukarıdan geldiği varsayılan değişkenler:
// $toplam_sayfa ve $sayfa
 
$sayfa_goster = 11; // gösterilecek sayfa sayısı
 
$en_az_orta = ceil($sayfa_goster/2);
$en_fazla_orta = ($toplam_sayfa+1) - $en_az_orta;
 
$sayfa_orta = $sayfa;
if($sayfa_orta < $en_az_orta) $sayfa_orta = $en_az_orta;
if($sayfa_orta > $en_fazla_orta) $sayfa_orta = $en_fazla_orta;
 
$sol_sayfalar = round($sayfa_orta - (($sayfa_goster-1) / 2));
$sag_sayfalar = round((($sayfa_goster-1) / 2) + $sayfa_orta); 
 
if($sol_sayfalar < 1) $sol_sayfalar = 1;
if($sag_sayfalar > $toplam_sayfa) $sag_sayfalar = $toplam_sayfa;
 
if($sayfa != 1) echo ' <a href="?sayfa=1">&lt;&lt;İlk sayfa</a> ';
if($sayfa != 1) echo ' <a href="?sayfa='.($sayfa-1).'">&lt;Önceki</a> ';
 
for($s = $sol_sayfalar; $s <= $sag_sayfalar; $s++) {
    if($sayfa == $s) {
        echo '[' . $s . '] ';
    } else {
        echo '<a href="?sayfa='.$s.'">'.$s.'</a> ';
    }
}
 
if($sayfa != $toplam_sayfa) echo ' <a href="?sayfa='.($sayfa+1).'">Sonraki&gt;</a> ';
if($sayfa != $toplam_sayfa) echo ' <a href="?sayfa='.$toplam_sayfa.'">Son sayfa&gt;&gt;</a>';

 

yukarıdaki kod parçacığı kullanıma hazırdır. değişken isimleri gibi detayları kendinize göre düzenleyip, kullanabilirsiniz.

phpr.org