Pendahuluan — daftar pinjam panjang butuh potongan
Artikel ini adalah #65 (ini) di Seri 5: Laravel Lanjutan. Setelah relasi anggota, buku, dan peminjaman selesai di Relasi Eloquent: Anggota & Peminjaman (#64), daftar slip pinjam di proyekmu mulai terasa panjang.
Satu respons yang memuat ratusan baris bikin lambat dan sulit dibaca. Hari ini kita belajar tiga gerakan dasar: filter status (aktif atau kembali), pencarian lewat ?q= pada judul buku atau nama anggota, lalu pagination supaya tiap halaman hanya menampilkan potongan kecil. Urutan yang benar: saring -> cari -> potong — jangan potong dulu baru saring.
Awam: bayangkan tumpukan slip pinjam di meja loket. Petugas tidak menyerahkan semua slip sekaligus. Dia memilih slip yang statusnya cocok, mencari nama atau judul buku yang kamu sebut, lalu hanya mengambil segenggam untuk halaman pertama. API daftar pinjam bekerja dengan logika yang sama; jawaban itu dibaca oleh pemanggil, yaitu aplikasi atau alat yang memanggil API.
Prasyarat: sudah selesai Relasi Eloquent: Anggota & Peminjaman (#64), paham fondasi Instal PHP, Composer & Proyek Laravel (#56) / Struktur Folder,
.env& Artisan Laravel (#57). Pakai Laravel 13+ — butuh PHP 8.3+.
Spesifikasi fitur — apa yang selesai hari ini?
Tiga hal ini yang kita kejar:
- Pagination — daftar pinjam dipotong per halaman dengan
pagedanper_page. - Filter status — hanya tampilkan slip
aktifataukembalilewat parameterstatus. - Pencarian — cari judul buku atau nama anggota lewat
?q=(bisa juga disebut kata kunci pencarian; di roadmap kita pakai namaq).
Awam: selesai artikel ini, kamu belum membangun izin siapa boleh ubah pinjam. Kamu sedang membuat daftar panjang terasa rapi untuk pemanggil API: tidak semua baris dilontarkan sekaligus, tapi dipilih dan dipotong dengan aturan yang jelas.
Istilah — ringkas untuk daftar panjang
| Istilah | Arti awam | Catatan |
|---|---|---|
| Pagination | Potong daftar per halaman | Halaman 1, halaman 2, dan seterusnya |
page |
Nomor halaman yang diminta | Mulai dari 1, bukan 0 |
per_page |
Jumlah baris per halaman | Misalnya 3 atau 10 baris |
Filter status |
Saring slip menurut kondisi pinjam | aktif atau kembali |
q |
Kata kunci pencarian | Cocokkan judul buku atau nama anggota |
Urutan belajar kita: filter status -> cari dengan q -> baru potong per halaman. Kalau urutan dibalik, hasil bisa salah karena baris yang tidak relevan ikut masuk ke potongan halaman.
Persiapan — alat yang kamu buka
Alat yang dipakai di artikel ini (fondasi dari Instal PHP, Composer & Proyek Laravel (#56) dan Struktur Folder, .env & Artisan Laravel (#57) — tidak ada unduhan Composer baru hari ini):
- Explorer — cek folder proyek
perpustakaan-api, lalu lihatapp\Http\Controllersuntuk pengatur kode daftar pinjam. - Terminal — Laragon: menu Terminal · XAMPP: tombol Shell. Hindari CMD/PowerShell dari Start Menu kalau PATH PHP-mu belum rapi.
- Editor teks — Notepad / VS Code — untuk membuka atau membuat pengatur kode. Contoh:
notepad app\Http\Controllers\PeminjamanController.php. - Browser — opsional. Inti uji hari ini ada di terminal; browser berguna kalau kamu sudah menjalankan
php artisan servedan ingin uji lewat alamat URL.
Awam: untuk artikel ini satu terminal sebenarnya cukup — jalankan php laravel_pagination_filter_pencarian_demo.php di folder proyek. Kalau php artisan serve dari artikel sebelumnya masih hidup, pakai terminal kedua untuk demo PHP dan perintah curl.exe saat menguji rute Laravel. Kalau butuh jendela kedua: Laragon — klik menu Terminal lagi · XAMPP — klik tombol Shell lagi, lalu cd ke folder proyek yang sama.
Buka terminal Laragon/Shell XAMPP, masuk ke folder proyek:
cd C:\laragon\www\perpustakaan-api
Di XAMPP biasanya: cd C:\xampp\htdocs\perpustakaan-api. Sesuaikan kalau foldermu beda.
Install-dari-nol: kalau php atau composer belum dikenali terminal, kembali dulu ke Instal PHP, Composer & Proyek Laravel (#56). Kalau struktur folder proyek masih membingungkan, ulangi Struktur Folder, .env & Artisan Laravel (#57).
Kenapa PHP biasa dulu?
Kalau langsung loncat ke paginate() di Laravel, pemula sering bingung urutan kerja: saring, cari, potong. Maka kita mulai dari array PHP biasa supaya setiap langkah terlihat jelas sebelum dibungkus Eloquent.
<?php
$daftar = [
["id" => 100, "judul_buku" => "Dasar PHP", "nama_anggota" => "Budi", "status" => "aktif"],
["id" => 101, "judul_buku" => "Belajar Laravel", "nama_anggota" => "Siti", "status" => "kembali"],
["id" => 102, "judul_buku" => "Dasar PHP", "nama_anggota" => "Andi", "status" => "aktif"],
["id" => 103, "judul_buku" => "Matematika", "nama_anggota" => "Budi", "status" => "kembali"],
["id" => 104, "judul_buku" => "Biologi", "nama_anggota" => "Rina", "status" => "aktif"],
["id" => 105, "judul_buku" => "Fisika", "nama_anggota" => "Dewi", "status" => "kembali"],
];
Awam: ini daftar gabungan seperti hasil relasi di artikel sebelumnya: tiap baris sudah punya judul_buku, nama_anggota, dan status. Pagination hanya mengatur berapa baris yang ditampilkan dari daftar ini.
Alur daftar — saring, cari, potong
Gerakan yang benar selalu sama:
- Saring status — kalau
status=aktif, buang slip yang sudah kembali. - Cari dengan
q— cocokkan kata kunci ke judul buku atau nama anggota. - Potong per halaman — ambil segenggam baris sesuai
pagedanper_page.
<?php
// Salin ke file misalnya daftar-saring.php lalu jalankan: php daftar-saring.php
$daftar = [
["id" => 100, "judul_buku" => "Dasar PHP", "nama_anggota" => "Budi", "status" => "aktif"],
["id" => 101, "judul_buku" => "Belajar Laravel", "nama_anggota" => "Siti", "status" => "kembali"],
["id" => 102, "judul_buku" => "Dasar PHP", "nama_anggota" => "Andi", "status" => "aktif"],
["id" => 103, "judul_buku" => "Matematika", "nama_anggota" => "Budi", "status" => "kembali"],
["id" => 104, "judul_buku" => "Biologi", "nama_anggota" => "Rina", "status" => "aktif"],
["id" => 105, "judul_buku" => "Fisika", "nama_anggota" => "Dewi", "status" => "kembali"],
];
$hasil = $daftar;
// 1) saring status
$status = "aktif";
$hasil = array_values(array_filter($hasil, fn ($row) => $row["status"] === $status));
// 2) cari q
$q = "php";
$hasil = array_values(array_filter($hasil, function ($row) use ($q) {
$needle = mb_strtolower($q);
return str_contains(mb_strtolower($row["judul_buku"]), $needle)
|| str_contains(mb_strtolower($row["nama_anggota"]), $needle);
}));
// 3) potong halaman
$page = 1;
$perPage = 2;
$offset = ($page - 1) * $perPage;
$potongan = array_slice($hasil, $offset, $perPage);
echo json_encode($potongan, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), PHP_EOL;
Awam — cara menguji bagian ini: salin potongan di atas ke daftar-saring.php, lalu di terminal jalankan php daftar-saring.php. Kalau muncul JSON berisi slip aktif yang judulnya mengandung “php”, urutan saring-cari-potong sudah sehat. Kalau kamu memotong dulu baru menyaring, halaman 2 bisa berisi slip yang seharusnya tidak ikut — urutan saring -> cari -> potong menjaga setiap halaman konsisten.
q, baru pagination memotong hasil.Laravel — cuplikan pagination & filter
Di proyek Laravel, pengatur kode daftar pinjam bisa membaca parameter URL lalu membangun query Eloquent dengan urutan yang sama.
<?php
// Cuplikan Laravel (bukan file mandiri)
// app/Http/Controllers/PeminjamanController.php
$status = request("status");
$q = request("q");
$perPage = (int) request("per_page", 10);
$query = Peminjaman::query()->with(["buku", "anggota"]);
if ($status) {
$query->where("status", $status);
}
if ($q) {
$query->where(function ($builder) use ($q) {
$builder->whereHas("buku", fn ($b) => $b->where("judul", "like", "%{$q}%"))
->orWhereHas("anggota", fn ($a) => $a->where("nama", "like", "%{$q}%"));
});
}
$hasil = $query->paginate($perPage);
Awam: paginate() otomatis menghitung total, halaman aktif, dan potongan data. whereHas memakai relasi dari artikel sebelumnya: cari judul lewat tabel buku, cari nama lewat tabel anggota. Parameter q adalah nama standar di roadmap kita; kata cari kadang dipakai di tutorial lain, tapi di sini kita konsisten dengan q. Cuplikan ini bukan file mandiri — tempel ke PeminjamanController kalau rute daftar pinjam sudah ada. Kalau belum, kuasai demo PHP dulu; urutan saring-cari-potong tetap sama.
Kalau php artisan serve sudah jalan di terminal pertama, uji di terminal kedua. Di Windows ketik curl.exe (bukan alias curl saja) supaya PowerShell tidak bingung:
curl.exe "http://127.0.0.1:8000/api/peminjaman?status=aktif&q=php&page=1&per_page=3"
Awam: respons JSON dari curl.exe adalah cara cepat melihat apakah filter, pencarian, dan pagination bekerja sebelum membuka browser. Kalau muncul 404, rute daftar pinjam mungkin belum dipasang — itu wajar; fokus dulu ke demo PHP yang sudah jalan di terminal.
Pola Dasar — daftar panjang yang rapi
-
1
Terima parameter URL
status,q,page,per_pagedari pemanggil API. -
2
Saring status dulu
Buang slip yang tidak cocok sebelum menghitung halaman. -
3
Cari dengan q
Cocokkan judul buku atau nama anggota dari kata kunci. -
4
Potong per halaman
Ambil segenggam baris sesuaipagedanper_page. -
5
Kembalikan metadata
page,per_page,total, dandatasupaya pemanggil tahu posisi daftar. -
6
Tolak halaman rusak
Kalaupagenol atau negatif, jawab 422 — bukan halaman kosong diam-diam.
Kode lengkap — demo mandiri daftar panjang
Simpan sebagai laravel_pagination_filter_pencarian_demo.php, lalu jalankan php laravel_pagination_filter_pencarian_demo.php:
<?php
declare(strict_types=1);
$daftar = [
["id" => 100, "judul_buku" => "Dasar PHP", "nama_anggota" => "Budi", "status" => "aktif"],
["id" => 101, "judul_buku" => "Belajar Laravel", "nama_anggota" => "Siti", "status" => "kembali"],
["id" => 102, "judul_buku" => "Dasar PHP", "nama_anggota" => "Andi", "status" => "aktif"],
["id" => 103, "judul_buku" => "Matematika", "nama_anggota" => "Budi", "status" => "kembali"],
["id" => 104, "judul_buku" => "Biologi", "nama_anggota" => "Rina", "status" => "aktif"],
["id" => 105, "judul_buku" => "Fisika", "nama_anggota" => "Dewi", "status" => "kembali"],
];
function daftarPinjam(
array $rows,
?string $status = null,
?string $q = null,
int $page = 1,
int $perPage = 3
): array {
if ($page < 1) {
return [
"status" => 422,
"error" => "Halaman tidak valid",
];
}
$hasil = $rows;
if ($status !== null && $status !== "") {
$hasil = array_values(array_filter($hasil, fn ($row) => $row["status"] === $status));
}
if ($q !== null && $q !== "") {
$needle = mb_strtolower($q);
$hasil = array_values(array_filter($hasil, function ($row) use ($needle) {
return str_contains(mb_strtolower($row["judul_buku"]), $needle)
|| str_contains(mb_strtolower($row["nama_anggota"]), $needle);
}));
}
$total = count($hasil);
$offset = ($page - 1) * $perPage;
$data = array_slice($hasil, $offset, $perPage);
return [
"status" => 200,
"page" => $page,
"per_page" => $perPage,
"total" => $total,
"data" => $data,
];
}
function demo(string $judul, callable $aksi): void
{
echo "=== {$judul} ===", PHP_EOL;
echo json_encode($aksi(), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), PHP_EOL, PHP_EOL;
}
demo("Halaman rusak -> 422", function () use ($daftar) {
return daftarPinjam($daftar, null, null, 0, 3);
});
demo("Status aktif + q php -> 200", function () use ($daftar) {
return daftarPinjam($daftar, "aktif", "php", 1, 3);
});
demo("Semua status halaman 2 -> 200", function () use ($daftar) {
return daftarPinjam($daftar, null, null, 2, 3);
});
Awam: tiga skenario di atas menunjukkan pola respons yang wajar: halaman invalid ditolak, filter + pencarian digabung, lalu pagination tanpa filter menampilkan halaman kedua. Fungsi daftarPinjam adalah inti logika; demo(...) hanya membungkus output agar mudah dibaca di terminal.
Kesalahan umum
| Gejala | Penyebab tipikal | Perbaikan awam |
|---|---|---|
| Halaman 2 kosong tapi total besar | Memotong dulu baru menyaring | Ubah urutan: saring -> cari -> potong |
| Pencarian tidak menemukan nama anggota | Hanya mencari di judul buku | Cari juga di nama_anggota atau relasi anggota |
page=0 mengembalikan data aneh |
Tidak memvalidasi nomor halaman | Kembalikan 422 untuk halaman tidak valid |
| Filter status diabaikan | Parameter URL tidak dibaca di pengatur kode | Baca request("status") sebelum membangun query |
curl aneh atau error di PowerShell |
Alias curl di PowerShell bukan curl.exe |
Ketik curl.exe persis seperti contoh, atau uji lewat browser |
Latihan singkat
- Tambah satu baris baru ke array demo, lalu cek apakah
totalikut berubah. - Coba
daftarPinjam($daftar, "kembali", "budi", 1, 2)dan jelaskan urutan saring-cari-potong yang terjadi. - Tulis satu kalimat: kenapa
qlebih fleksibel daripada hanya filter judul buku?
FAQ singkat
Kenapa tidak langsung policy atau resource?
Karena daftar harus rapi dulu sebelum membahas izin ubah pinjam atau format JSON yang lebih cantik. Artikel ini fokus pada pagination, filter, dan pencarian.
Beda q dan cari?
Keduanya bisa berarti kata kunci pencarian. Di roadmap Seri 5 kita pakai q supaya konsisten di artikel berikutnya.
Tool apa yang dibuka dulu?
Explorer untuk memastikan folder proyek benar, satu terminal untuk demo PHP, editor untuk pengatur kode. Kalau serve hidup, terminal kedua untuk curl.exe.
Potongan sintaks diuji di mana?
Langkah tengah (saring-cari-potong) salin ke daftar-saring.php, lalu jalankan php daftar-saring.php. Demo lengkap diuji dengan php laravel_pagination_filter_pencarian_demo.php. Cuplikan Laravel ditempel ke app\Http\Controllers\PeminjamanController.php; kalau rute sudah ada, uji dengan curl.exe di terminal kedua.
Ke mana setelah ini?
Berikutnya alami: Authorization Policy — aturan izin siapa boleh mengubah catatan pinjam.
Kesimpulan
Kamu sudah belajar memotong daftar pinjam panjang dengan urutan yang benar: saring status -> cari dengan q -> potong per halaman. Mulai dari array PHP dulu, lalu pindah ke paginate() dan whereHas di Laravel. Setelah ini, daftar terasa rapi untuk pemanggil API sebelum kita membahas izin.
Seri 5 progress: langkah #65 (ini) · 2/7 Laravel Lanjutan · prasyarat: Relasi Eloquent: Anggota & Peminjaman (#64) LIVE. Berikutnya: Authorization Policy.