Pagination adalah fitur navigasi yang memungkinkan pengguna untuk berpindah antar halaman dalam dataset yang besar. Dengan menggunakan PHP dan Bootstrap, kita dapat membuat pagination yang tidak hanya fungsional tetapi juga memiliki tampilan yang menarik dan responsif di semua perangkat.
Mengapa Pagination Penting?
Pagination sangat penting untuk website dengan data yang banyak karena:
- Performa: Mengurangi waktu loading dengan membatasi data per halaman
- User Experience: Memudahkan navigasi dan pencarian data
- SEO: Membantu search engine mengindex konten dengan lebih baik
- Bandwidth: Menghemat penggunaan bandwidth server dan client
- Responsif: Tampilan yang optimal di berbagai ukuran layar
Persiapan dan Requirements
Sebelum membuat pagination, pastikan Anda memiliki:
- PHP 7.4 atau lebih baru
- Database MySQL/MariaDB
- Bootstrap 5 (atau versi terbaru)
- Web server (Apache/Nginx)
- Text editor atau IDE
Langkah 1: Setup Database dan Koneksi
Pertama, buat tabel sample dan koneksi database:
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
author VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);– Insert data sample
INSERT INTO articles (title, content, author) VALUES
(‘Tutorial PHP Dasar’, ‘Konten artikel tentang PHP dasar…’, ‘Admin’),
(‘Belajar Bootstrap’, ‘Konten artikel tentang Bootstrap…’, ‘Developer’),
(‘JavaScript Modern’, ‘Konten artikel tentang JavaScript…’, ‘Programmer’);
— Tambahkan lebih banyak data untuk testing pagination
// config.php – Koneksi Database
$host = ‘localhost’;
$dbname = ‘nama_database’;
$username = ‘root’;
$password = ”;try {
$pdo = new PDO(“mysql:host=$host;dbname=$dbname;charset=utf8mb4”, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
die(“Koneksi gagal: ” . $e->getMessage());
}
?>
Langkah 2: Membuat Class Pagination
Buat class PHP untuk menangani logika pagination:
// Pagination.php
class Pagination {
private $pdo;
private $limit;
private $page;
private $total;
private $offset;public function __construct($pdo, $limit = 10) {
$this->pdo = $pdo;
$this->limit = $limit;
$this->page = isset($_GET[‘page’]) ? (int)$_GET[‘page’] : 1;
$this->page = max(1, $this->page); // Minimal halaman 1
$this->offset = ($this->page – 1) * $this->limit;
}public function getData($table, $conditions = ”, $params = []) {
// Hitung total data
$countSql = “SELECT COUNT(*) FROM $table”;
if ($conditions) {
$countSql .= ” WHERE $conditions”;
}
$countStmt = $this->pdo->prepare($countSql);
$countStmt->execute($params);
$this->total = $countStmt->fetchColumn();
// Ambil data dengan limit
$dataSql = “SELECT * FROM $table”;
if ($conditions) {
$dataSql .= ” WHERE $conditions”;
}
$dataSql .= ” ORDER BY id DESC LIMIT {$this->limit} OFFSET {$this->offset}”;
$dataStmt = $this->pdo->prepare($dataSql);
$dataStmt->execute($params);
return $dataStmt->fetchAll(PDO::FETCH_ASSOC);
}
public function getTotalPages() {
return ceil($this->total / $this->limit);
}
public function getCurrentPage() {
return $this->page;
}
public function getTotal() {
return $this->total;
}
public function hasNext() {
return $this->page < $this->getTotalPages();
}
public function hasPrev() {
return $this->page > 1;
}
}
?>
Langkah 3: Membuat HTML dengan Bootstrap
Buat halaman utama dengan tampilan Bootstrap:
<html lang=”id”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<title>Pagination PHP Bootstrap</title>
<link href=”https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css” rel=”stylesheet”>
</head>
<body>
<div class=”container mt-5″>
<h1 class=”mb-4″>Daftar Artikel</h1><!– Search Form –>
<form method=”GET” class=”mb-4″>
<div class=”row”>
<div class=”col-md-8″>
<input type=”text” name=”search” class=”form-control”
placeholder=”Cari artikel…” value=”<?= htmlspecialchars($_GET[‘search’] ?? ”) ?>”>
</div>
<div class=”col-md-4″>
<button type=”submit” class=”btn btn-primary”>Cari</button>
<a href=”?” class=”btn btn-secondary”>Reset</a>
</div>
</div>
</form><!– Articles List –>
<div id=”articles-container”>
<!– Konten artikel akan dimuat di sini –>
</div>
<!– Pagination –>
<nav aria-label=”Page navigation”>
<ul class=”pagination justify-content-center” id=”pagination-container”>
<!– Pagination akan dimuat di sini –>
</ul>
</nav>
</div>
<script src=”https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js”></script>
</body>
</html>
Langkah 4: Implementasi Pagination Logic
Buat file PHP untuk menangani data dan pagination:
// index.php
require_once ‘config.php’;
require_once ‘Pagination.php’;// Inisialisasi pagination
$pagination = new Pagination($pdo, 5); // 5 artikel per halaman// Handle search
$search = $_GET[‘search’] ?? ”;
$conditions = ”;
$params = [];
if (!empty($search)) {
$conditions = “title LIKE :search OR content LIKE :search OR author LIKE :search”;
$params[‘:search’] = “%$search%”;
}
// Ambil data
$articles = $pagination->getData(‘articles’, $conditions, $params);
$totalPages = $pagination->getTotalPages();
$currentPage = $pagination->getCurrentPage();
$total = $pagination->getTotal();
?>
<!– Tampilkan informasi –>
<div class=”alert alert-info”>
Menampilkan <strong><?= count($articles) ?></strong> dari <strong><?= $total ?></strong> artikel
(Halaman <strong><?= $currentPage ?></strong> dari <strong><?= $totalPages ?></strong>)
</div>
<!– Tampilkan artikel –>
<?php if (empty($articles)): ?>
<div class=”alert alert-warning”>Tidak ada artikel yang ditemukan.</div>
<?php else: ?>
<?php foreach ($articles as $article): ?>
<div class=”card mb-3″>
<div class=”card-body”>
<h5 class=”card-title”><?= htmlspecialchars($article[‘title’]) ?></h5>
<p class=”card-text”><?= substr(htmlspecialchars($article[‘content’]), 0, 150) ?>…</p>
<p class=”card-text”>
<small class=”text-muted”>
Oleh: <?= htmlspecialchars($article[‘author’]) ?> |
<?= date(‘d M Y’, strtotime($article[‘created_at’])) ?>
</small>
</p>
<a href=”detail.php?id=<?= $article[‘id’] ?>” class=”btn btn-primary btn-sm”>Baca Selengkapnya</a>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
Langkah 5: Membuat Komponen Pagination Bootstrap
Buat function untuk generate pagination Bootstrap:
function generatePagination($currentPage, $totalPages, $search = ”) {
if ($totalPages <= 1) return ”; $html = ”; $searchParam = !empty($search) ? “&search=” . urlencode($search) : ”; // Previous button if ($currentPage > 1) {
$prevPage = $currentPage – 1;
$html .= “<li class=’page-item’>”;
$html .= “<a class=’page-link’ href=’?page=$prevPage$searchParam’>Previous</a>”;
$html .= “</li>”;
} else {
$html .= “<li class=’page-item disabled’>”;
$html .= “<span class=’page-link’>Previous</span>”;
$html .= “</li>”;
}// Page numbers
$start = max(1, $currentPage – 2);
$end = min($totalPages, $currentPage + 2);// First page
if ($start > 1) {
$html .= “<li class=’page-item’>”;
$html .= “<a class=’page-link’ href=’?page=1$searchParam’>1</a>”;
$html .= “</li>”;
if ($start > 2) {
$html .= “<li class=’page-item disabled’><span class=’page-link’>…</span></li>”;
}
}
// Page range
for ($i = $start; $i <= $end; $i++) {
if ($i == $currentPage) {
$html .= “<li class=’page-item active’>”;
$html .= “<span class=’page-link’>$i</span>”;
$html .= “</li>”;
} else {
$html .= “<li class=’page-item’>”;
$html .= “<a class=’page-link’ href=’?page=$i$searchParam’>$i</a>”;
$html .= “</li>”;
}
}
// Last page
if ($end < $totalPages) {
if ($end < $totalPages – 1) {
$html .= “<li class=’page-item disabled’><span class=’page-link’>…</span></li>”;
}
$html .= “<li class=’page-item’>”;
$html .= “<a class=’page-link’ href=’?page=$totalPages$searchParam’>$totalPages</a>”;
$html .= “</li>”;
}
// Next button
if ($currentPage < $totalPages) {
$nextPage = $currentPage + 1;
$html .= “<li class=’page-item’>”;
$html .= “<a class=’page-link’ href=’?page=$nextPage$searchParam’>Next</a>”;
$html .= “</li>”;
} else {
$html .= “<li class=’page-item disabled’>”;
$html .= “<span class=’page-link’>Next</span>”;
$html .= “</li>”;
}
return $html;
}
// Tampilkan pagination
echo generatePagination($currentPage, $totalPages, $search);
?>
Langkah 6: AJAX Pagination (Optional)
Untuk pengalaman yang lebih smooth, tambahkan AJAX pagination:
// AJAX Pagination
$(document).ready(function() {
// Handle pagination clicks
$(document).on(‘click’, ‘.pagination a’, function(e) {
e.preventDefault();var url = $(this).attr(‘href’);
loadPage(url);
});// Handle search form
$(‘#search-form’).on(‘submit’, function(e) {
e.preventDefault();
var formData = $(this).serialize();
var url = ‘?’ + formData;
loadPage(url);
});
function loadPage(url) {
// Show loading
$(‘#articles-container’).html(‘<div class=”text-center”><div class=”spinner-border”></div></div>’);
$.get(url)
.done(function(data) {
// Update content
var $data = $(data);
$(‘#articles-container’).html($data.find(‘#articles-container’).html());
$(‘#pagination-container’).html($data.find(‘#pagination-container’).html());
// Update URL without reload
window.history.pushState({}, ”, url);
})
.fail(function() {
$(‘#articles-container’).html(‘<div class=”alert alert-danger”>Terjadi kesalahan saat memuat data.</div>’);
});
}
});
</script>
Langkah 7: Responsive Design dan Customization
Tambahkan CSS custom untuk tampilan yang lebih baik:
/* Custom Pagination Styles */
.pagination {
margin: 2rem 0;
}.pagination .page-link {
color: #007bff;
border: 1px solid #dee2e6;
padding: 0.5rem 0.75rem;
margin: 0 2px;
border-radius: 0.375rem;
transition: all 0.3s ease;
}.pagination .page-link:hover {
background-color: #e9ecef;
border-color: #adb5bd;
transform: translateY(-1px);
}
.pagination .page-item.active .page-link {
background-color: #007bff;
border-color: #007bff;
color: white;
box-shadow: 0 2px 4px rgba(0,123,255,0.3);
}
.pagination .page-item.disabled .page-link {
color: #6c757d;
background-color: #fff;
border-color: #dee2e6;
}
/* Responsive adjustments */
@media (max-width: 576px) {
.pagination {
font-size: 0.875rem;
}
.pagination .page-link {
padding: 0.375rem 0.5rem;
margin: 0 1px;
}
/* Hide page numbers on mobile, show only prev/next */
.pagination .page-item:not(.prev):not(.next) {
display: none;
}
.pagination .page-item.active {
display: inline-block;
}
}
/* Loading animation */
.spinner-border {
width: 3rem;
height: 3rem;
}
/* Card hover effects */
.card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
</style>
Langkah 8: Optimasi dan Best Practices
- Database Index: Buat index pada kolom yang sering dicari
- Caching: Implementasikan caching untuk query yang sering diakses
- Validation: Validasi input page number untuk keamanan
- SEO Friendly: Gunakan URL yang SEO friendly
- Performance: Monitor query performance dengan EXPLAIN
// Optimasi dengan prepared statements dan validation
class OptimizedPagination extends Pagination {public function validatePage($page) {
$page = filter_var($page, FILTER_VALIDATE_INT);
if ($page === false || $page < 1) { return 1; } $maxPage = $this->getTotalPages();
return min($page, $maxPage);
}public function getDataWithCache($table, $conditions = ”, $params = [], $cacheTime = 300) {
$cacheKey = md5($table . $conditions . serialize($params) . $this->page);
// Check cache (implementasi sesuai cache system yang digunakan)
if ($cachedData = $this->getFromCache($cacheKey)) {
return $cachedData;
}
$data = $this->getData($table, $conditions, $params);
// Save to cache
$this->saveToCache($cacheKey, $data, $cacheTime);
return $data;
}
}
?>
Contoh Implementasi Lengkap
Berikut contoh implementasi pagination yang siap digunakan:
// complete-example.php
require_once ‘config.php’;
require_once ‘Pagination.php’;try {
// Setup pagination
$itemsPerPage = $_GET[‘limit’] ?? 10;
$itemsPerPage = min(50, max(5, (int)$itemsPerPage)); // Batasi 5-50$pagination = new Pagination($pdo, $itemsPerPage);
// Handle search and filters
$search = trim($_GET[‘search’] ?? ”);
$category = $_GET[‘category’] ?? ”;
$conditions = [];
$params = [];
if (!empty($search)) {
$conditions[] = “(title LIKE :search OR content LIKE :search)”;
$params[‘:search’] = “%$search%”;
}
if (!empty($category)) {
$conditions[] = “category = :category”;
$params[‘:category’] = $category;
}
$whereClause = !empty($conditions) ? implode(‘ AND ‘, $conditions) : ”;
// Get data
$articles = $pagination->getData(‘articles’, $whereClause, $params);
// Pagination info
$paginationInfo = [
‘current’ => $pagination->getCurrentPage(),
‘total’ => $pagination->getTotalPages(),
‘count’ => count($articles),
‘totalRecords’ => $pagination->getTotal()
];
} catch (Exception $e) {
error_log($e->getMessage());
$articles = [];
$paginationInfo = [‘current’ => 1, ‘total’ => 0, ‘count’ => 0, ‘totalRecords’ => 0];
}
?>
Untuk mempelajari lebih lanjut tentang optimasi PHP, silakan baca artikel kami tentang teknik optimasi performa PHP yang akan membantu meningkatkan kecepatan aplikasi web Anda.
Jika Anda ingin mendalami Bootstrap lebih lanjut, kami juga menyediakan tutorial tentang Bootstrap responsive design yang sangat berguna untuk membuat website yang mobile-friendly.
Untuk tutorial web development lainnya, kunjungi Kelas Programmer yang menyediakan materi pembelajaran lengkap dari dasar hingga advanced.
Kesimpulan
Pagination PHP Bootstrap adalah kombinasi yang powerful untuk membuat navigasi halaman yang elegan dan responsif. Dengan mengikuti tutorial ini, Anda dapat membuat pagination yang tidak hanya fungsional tetapi juga memberikan user experience yang excellent. Pastikan untuk selalu memperhatikan performa, keamanan, dan responsivitas dalam implementasi pagination Anda.
❓ FAQ (Frequently Asked Questions)
Q: Bagaimana cara menentukan jumlah item per halaman yang optimal?
A: Jumlah optimal biasanya 10-20 item per halaman untuk desktop dan 5-10 untuk mobile. Pertimbangkan ukuran data, kecepatan loading, dan user experience. Berikan opsi untuk user memilih jumlah item per halaman.
Q: Apakah pagination mempengaruhi SEO website?
A: Ya, pagination yang baik dapat meningkatkan SEO. Gunakan URL yang SEO-friendly, tambahkan rel=”prev” dan rel=”next”, serta pastikan semua halaman dapat diakses oleh search engine crawler.
Q: Bagaimana cara membuat pagination yang responsive di mobile?
A: Gunakan Bootstrap classes seperti d-none d-md-block untuk menyembunyikan nomor halaman di mobile, tampilkan hanya Previous/Next dan halaman aktif. Gunakan touch-friendly button size.
Q: Apakah lebih baik menggunakan AJAX atau reload halaman untuk pagination?
A: AJAX memberikan user experience yang lebih smooth, tetapi reload halaman lebih SEO-friendly. Kombinasi keduanya (progressive enhancement) adalah solusi terbaik – fallback ke reload jika JavaScript disabled.
Q: Bagaimana cara mengoptimalkan performa pagination untuk database besar?
A: Gunakan database indexing pada kolom yang sering diquery, implementasikan caching, gunakan LIMIT dan OFFSET dengan bijak, dan pertimbangkan cursor-based pagination untuk dataset yang sangat besar.
🔗 Backlinks yang Disertakan