Pagination (Sayfalama) Nedir?
Pagination, bir web sitesi veya uygulamasındaki büyük veri kümesini daha yönetilebilir ve kullanıcı dostu parçalara bölmek için kullanılan bir tasarım ve kullanıcı deneyimi öğesidir. Bu özellik, uzun listeler, tablolar veya sonu gelmeyen bir içerik akışı gibi durumlarda kullanılır.
Pagination'ın temel amacı, kullanıcılara içeriği daha küçük ve erişilebilir parçalar halinde sunarak aşağıdaki avantajları sağlamaktır:
- Kullanıcı Dostu: Büyük bir içerik kümesini sınırlı sayıda öğeyle göstererek, kullanıcıların daha rahat ve hızlı bir şekilde gezinmesini sağlar.
- Yük Performansı: Pagination, bir sayfayı yüklemek için gereken veri miktarını azaltır, bu da sayfanın daha hızlı yüklenmesine ve böylece daha iyi bir performansa yol açar.
- Navigasyon Kolaylığı: Kullanıcılar, sayfalandırma düğmeleri veya sayfa numaraları gibi araçlarla sayfalar arasında geçiş yapabilirler.
- Arama ve Filtreleme Kolaylığı: Sayfalandırma, kullanıcıların içerikte hızlıca arama yapmalarını veya belirli öğeleri filtrelemelerini kolaylaştırabilir.
Pagination, genellikle "Önceki Sayfa" ve "Sonraki Sayfa" düğmeleri ile birlikte gelir, böylece kullanıcılar bir sayfa sonunda bulunan veriden diğerine geçebilirler. Sayfalandırma, web sitelerinde, e-ticaret platformlarında, forumlarda ve birçok diğer yerde büyük veri kümeleri ile karşılaşılan bir sorunu çözmek için yaygın olarak kullanılan bir tasarım öğesidir.
PHP ile Pagination Yapımı
Bu yazımızda hesaplamayı yapan ve HTML çıktısını veren olmak üzere iki fonksiyon yapacağız. Bu iki fonksiyonu birbirinden ayırmamızın nedeni farklı tasarımlara rahatlıkla entegre edebilecek olmamızdır. Örnek olarak Bootstrap 5 üzerinde hazır bulunan html çıktısını vereceğiz. Daha sonra siz kendi projenize göre HTML'i değiştirebilirsiniz.
Google sonuçlarından aşina olduğumuz string üzerinden fonksiyonumuzu anlatalım. Google Örneği: "165.000 sonuçtan 51 ile 60 arasındakiler gösteriliyor"
İlk önce pagination() fonksiyonunu hazırlıyoruz. Bu fonksiyona vermemiz gereken parametreler;
- $totalResults: Örneğimizdeki 165.000'e karşılık geliyor
- $activePage: Kaçıncı sayfada bulunduğumuz. Google örneğinde her sayfada 10 sonuç gösterildiğinden 6. sayfada olduğunu anlıyoruz. Bu parametreyi $_GET metodu ile alacağız.
- $resultsPerPage: Google'da sayfa başına 10 sonuç olan örneğimiz, bizde grid yapısına daha uygun olması için 12 varsayılanıyla yapıyoruz.
- $maxPage: Çok fazla sonuç döndüğünde pagination'umuz çöplüğe dönmesin diye limit belirliyoruz. Varsayılan 7 örneğinde --- << | < | 3 | 4 | 5 | 6 (aktif sayfa) | 7 | 8 | 9 | > | >> --- şeklinde olacaktır.
Şimdi pagination() fonksiyonumuzu yazalım
function pagination(int $totalResults, int $activePage, int $resultsPerPage = 12, int $maxPage = 7):stdClass {
// return için hazırlık yapıyoruz
$return = new stdClass();
$return->totalResults = $totalResults;
$return->activePage = $activePage;
$return->resultsPerPage = $resultsPerPage;
// Toplam sayfa sayısını hesaplıyoruz, ve küsüratlı olması durumunda yukarı yuvarlıyoruz
$return->numberOfPages = (int)ceil($totalResults / $resultsPerPage);
// Burada google örneğimizdeki stringi yazmak için gereken değişkenleri hesaplatıyoruz
// 165.000 sonuç arasından 51 ile 60 arasındakiler gösteriliyor
// ===
// $totalResults sonuç arasından $start ve $end arasındakiler gösteriliyor
// Aynı zamanda sonuçları sayfamızda listeletirken yazacağımız SQL koduna LIMIT stringi hazırlıyoruz
$return->startSQL = (int)ceil(($activePage-1) * $resultsPerPage);
$return->start = $totalResults > 0 ? $return->startSQL + 1 : 0;
$return->end = min($activePage * $resultsPerPage, $totalResults);
$return->limit = $return->startSQL.', '.$resultsPerPage;
// Eğer hesaplama sonuçları birden fazla sayfa olduğunu söylüyorsa, HTML çıktısı için verileri hazırlıyoruz
// Toplam sonuç sayısı 1 sayfadan fazla değilse HTML çıktısını göstermeyeceğiz
if ($totalResults > $resultsPerPage) {
$maxPageHalf = floor($maxPage/2);
$links = [];
$links['firstPage'] = $activePage - $maxPageHalf > 1 ? 1 : false;
$links['previousPage'] = $activePage > 1 ? $activePage - 1 : false;
$links['nextPage'] = $return->numberOfPages > $activePage ? $activePage + 1 : false;
$links['lastPage'] = $return->numberOfPages - $maxPageHalf > $activePage ? $return->numberOfPages : false;
$links['pages'] = [];
$filters = [
'min' => $activePage - $maxPageHalf,
'max' => $activePage + $maxPageHalf,
];
for ($i = 1; $i <= $return->numberOfPages; $i++) {
if ($i < $filters['min'] || $i > $filters['max']) continue;
$links['pages'][] = [
'page' => $i,
'active' => $i === $activePage,
];
}
$return->links = $links;
} else {
// hesaplama sonucu 1 sayfadan büyük olmadığı için pagination gösterilmeyecek
$return->links = [];
}
return $return;
}
Hesaplamaları yapmak için kullanacağımız fonksiyonumuzu oluşturduk. Şimdi de bu fonksiyonumuzdan dönen değerleri HTML koduna dönüştürecek olan fonksiyonumuzu oluşturuyoruz.
function paginationHTML(array $links, string $url):string {
$return = '';
// Eğer birden fazla sayfa sayısı yoksa, buraya boş bir dizi(array) gelecektir
// Bu durumda return çıktısını boş göndereceğiz
if (count($links)) {
// Pagination itemlerinin dışındaki kapsayıcı html kısmını yazıyoruz
// Örneğimizde Bootstrap 5 kullanıyoruz, ama siz kendi projenize göre class'ları düzenleyebilirsiniz
$return .= '<nav aria-label="Navigation"><ul class="pagination justify-content-center">';
if ($links['firstPage']) {
$href = str_replace('{p}', $links['firstPage'], $url);
$return .= '<li class="page-item"><a href="'.$href.'" class="page-link prev">«</a></li>';
}
if ($links['previousPage']) {
$href = str_replace('{p}', $links['previousPage'], $url);
$return .= '<li class="page-item"><a href="'.$href.'" class="page-link prev">‹</a></li>';
}
foreach ($links['pages'] as $item) {
$href = str_replace('{p}', $item['page'], $url);
$c = [
'li' => $item['active'] ? ' class="page-item disabled"' : ' class="page-item"',
'a' => $item['active'] ? ' href="'.$href.'" onclick="return false" class="page-link" tabindex="-1"' : ' href="'.$href.'" class="page-link"',
];
$return .= '<li'.$c['li'].'><a'.$c['a'].'>'.$item['page'].'</a></li>';
}
if ($links['nextPage']) {
$href = str_replace('{p}', $links['nextPage'], $url);
$return .= '<li class="page-item"><a href="'.$href.'" class="page-link next">›</a></li>';
}
if ($links['lastPage']) {
$href = str_replace('{p}', $links['lastPage'], $url);
$return .= '<li class="page-item"><a href="'.$href.'" class="page-link next">»</a></li>';
}
// Kapsayıcı HTML'i kapatıyoruz
$return .= '</ul></nav>';
}
return $return;
}
Evet. Gerekli fonksiyonlarımızı yazdık. Şimdi de nasıl kullancağımızı öğrenelim.
// Örnek URL: https://example.com/blog.php?p=7
// Örnek Toplam Sonuç: 751
// Bulunulan Sayfa: 7
// İlk önce kaçıncı sayfada olduğumuzu öğreniyoruz
$activePage = intval($_GET['p'] ?? 1);
// sayfa no 1'den küçük olamaz, o yüzden 1'den küçükse değerini 1 yapıyoruz
if ($activePage < 1) {
$activePage = 1;
}
// Veritabanında şartlara uyan kaç sonuç olduğunu sorguluyoruz
$query = $db->query('SELECT COUNT(*) as total FROM blog WHERE status = 1');
$result = $query->fetch();
$totalResults = $result->total; // örneğimiz 751 sonuç
// elimizdeki parametreleri kullanarak pagination hesaplamalarını yapıyoruz
$pagination = pagination($totalResults, $activePage, 10, 5);
// hesaplama sonrası dönen değerlere göre HTML koduna dönüştürüyoruz
// Eğer $pagination->links değeri boş array olursa HTML çıktısı boş string olacaktır
$paginationHTML = paginationHTML($pagination->links, 'https://example.com/blog.php?p={p}');
// google örneğimizdeki stringi bu şekilde yazdırabiliriz
$googleLikeString = "$pagination->totalResults sonuç arasından $pagination->start ile $pagination->end arasındakiler gösteriliyor";
// sonuçları veritabanından döndürürken bu şekilde LIMIT kullanıyoruz.
// bulunulan sayfa 7 olduğu için ve sayfa başına sonucu 10 olarak belirlediğimiz için SQL kodu şöyle olacaktır
// limit = (7 * 10)-1 = 69
// SELECT * FROM blog WHERE status = 1 ORDER BY id DESC LIMIT 69, 10
$query = $db->query("SELECT * FROM blog WHERE status = 1 ORDER BY id DESC LIMIT $pagination->limit");
while ($result = $query->fetch()) {
// sonuçlar
}
// alt kısıma da pagination HTML çıktısını yazdırıyoruz
echo $paginationHTML;
Bu şekilde basit bir pagination yaptık. Örnek çıktıları buraya tıklayarak görebilirsiniz.