Collection adalah array yang dibungkus objek, dengan method yang bisa dirangkai: saring, ubah, ambil satu kolom, kelompokkan, jumlahkan. Bayangin dapur Warung Bu Tini pakai ban berjalan. Piring lewat satu per satu pos: pos pertama menyisihkan menu di bawah Rp7.000, pos kedua mencatat namanya, pos terakhir menghitung totalnya. Tiap pos mengerjakan satu hal, dan urutannya terbaca dari kiri ke kanan. Lesson terakhir sebelum Generators ini juga merangkum dua fitur PHP modern yang sering dipakai bareng collection: enum dan match.
🧪 Tebakan cepat:
echo collect([1, 2, 3, 4, 5])->filter(fn ($n) => $n > 3);mencetak[4,5]atau{"3":4,"4":5}? Tebak dulu, jawabannya ada di bagian "Key ikut terbawa".
Tanpa collection: fungsi array bersarang
Ini data menu yang dipakai sepanjang lesson, harga yang sama dengan di Array Lanjutan:
<?php
$menu = [
["nama" => "Nasi Goreng", "kategori" => "makanan", "harga" => 15000],
["nama" => "Mie Ayam", "kategori" => "makanan", "harga" => 12000],
["nama" => "Es Teh", "kategori" => "minuman", "harga" => 5000],
["nama" => "Kerupuk", "kategori" => "camilan", "harga" => 2000],
["nama" => "Es Jeruk", "kategori" => "minuman", "harga" => 7000],
];
echo json_encode(array_column(array_filter($menu, fn ($m) => $m["harga"] >= 7000), "nama"));
// ["Nasi Goreng","Mie Ayam","Es Jeruk"]
Hasilnya benar, tapi bacanya dari dalam ke luar: array_filter dulu (paling dalam), lalu array_column, lalu json_encode. Tambah satu langkah lagi, dan kurungnya makin dalam.
Class Koleksi: method yang dirangkai
Bungkus array-nya dalam class (OOP Dasar), dan buat tiap method mengembalikan Koleksi baru:
class Koleksi {
public function __construct(private array $isi) {}
public function filter(callable $syarat): Koleksi {
return new Koleksi(array_filter($this->isi, $syarat));
}
public function pluck(string $kolom): Koleksi {
return new Koleksi(array_column($this->isi, $kolom));
}
public function sum(string $kolom): int {
return array_sum(array_column($this->isi, $kolom));
}
public function all(): array {
return $this->isi;
}
}
$hasil = (new Koleksi($menu))
->filter(fn ($m) => $m["harga"] >= 7000)
->pluck("nama")
->all();
echo json_encode($hasil); // ["Nasi Goreng","Mie Ayam","Es Jeruk"]
- Karena
filter()danpluck()mengembalikanKoleksi, method berikutnya bisa langsung ditempel dengan->. Ini namanya method chaining. - Urutannya sekarang terbaca dari atas ke bawah, persis urutan kerjanya.
- Isinya tetap fungsi array yang sama. Class-nya cuma membuat urutannya enak dibaca.
Laravel Collections
Laravel sudah punya class seperti ini, jauh lebih lengkap: Illuminate\Support\Collection, dibuat dengan fungsi collect(). Output di bawah ini dari Laravel 13 dan PHP 8.4:
echo collect($menu)->filter(fn ($m) => $m["harga"] >= 7000)->pluck("nama");
// ["Nasi Goreng","Mie Ayam","Es Jeruk"]
echo collect($menu)->groupBy("kategori")->map(fn ($g) => $g->pluck("nama"));
// {"makanan":["Nasi Goreng","Mie Ayam"],"minuman":["Es Teh","Es Jeruk"],"camilan":["Kerupuk"]}
echo collect($menu)->sum("harga"); // 41000
echo collect([10, 20, 30])->sum(); // 60
echo collect([1, 2, 3, 4])->map(fn ($n) => $n * 2)->last(); // 8
collect($array)membungkus array jadi collection.filter()menyaring dengan callback,map()mengubah tiap isi,pluck("nama")mengambil satu kolom dari tiap baris.groupBy("kategori")mengelompokkan baris menurut kolom itu.sum()menjumlahkan (sum("harga")menjumlahkan satu kolom),first()danlast()mengambil isi pertama dan terakhir.echosebuah collection mencetaknya sebagai JSON, dan->all()mengembalikan array biasa.- Di luar Laravel, pasang dengan
composer require illuminate/collections.
Di contoh terakhir, map() mengubah [1, 2, 3, 4] jadi [2, 4, 6, 8], lalu last() mengambil 8.
Key ikut terbawa
filter(), sama seperti array_filter di Array Lanjutan, mempertahankan key lama. Dari [1, 2, 3, 4, 5] yang lolos adalah key 3 (isinya 4) dan key 4 (isinya 5). Key-nya gak mulai dari 0 lagi, jadi JSON-nya jadi objek:
echo collect([1, 2, 3, 4, 5])->filter(fn ($n) => $n > 3); // {"3":4,"4":5}
echo collect([1, 2, 3, 4, 5])->filter(fn ($n) => $n > 3)->values(); // [4,5]
Jadi jawaban tebakannya {"3":4,"4":5}. values() (atau array_values() untuk array biasa) menomori ulang dari 0. Tanpa itu, ->get(0) setelah filter mengembalikan null, karena key 0 sudah gak ada. pluck() dan array_column() selalu menomori ulang, makanya contoh nama menu di atas sudah rapi.
Enum dan match, dipakai bareng
Kolom kategori cuma boleh tiga nilai. Enum (OOP Lanjutan) menjadikannya tipe, dan match (Kontrol Alur) memetakannya:
enum Kategori: string {
case Makanan = "makanan";
case Minuman = "minuman";
case Camilan = "camilan";
public function bisaDiantar(): bool {
return $this !== Kategori::Camilan;
}
}
function labelKategori(Kategori $k): string {
return match ($k) {
Kategori::Makanan => "Menu utama",
default => "Pelengkap",
};
}
echo labelKategori(Kategori::Makanan) . "\n"; // Menu utama
echo labelKategori(Kategori::from("minuman")) . "\n"; // Pelengkap
var_export(Kategori::Camilan->bisaDiantar()); // false
enum Kategori: stringadalah backed enum: tiapcasemembawa nilai string, danKategori::from("minuman")mengubah teks dari data jadi case-nya.- Enum boleh punya method. Di dalamnya,
$thisadalah case yang sedang dipakai. matchmencocokkan case satu per satu. Case yang gak disebut jatuh kedefault, jadiMinumandanCamilansama-sama jadi "Pelengkap".- Parameter bertipe
Kategorimenolak teks biasa:labelKategori("makanan")melemparTypeError.
⚠️ Jebakan yang sering ketemu
- Lupa key ikut terbawa.
filter()lalu[0]atau->get(0)bisanull, dan JSON-nya berubah jadi objek. Tambahkan->values(). - Mengira method mengubah collection aslinya.
filter(),map()danpluck()mengembalikan collection baru.collect($menu)->filter(...)tanpa disimpan atau dirangkai hilang begitu saja. collect()di luar Laravel. Tanpa paketilluminate/collections, PHP berhenti denganCall to undefined function collect().matchtanpadefault. Case yang gak disebut melemparUnhandledMatchError. Sebut semua case, atau tutup dengandefault.
TL;DR: Collection membungkus array dalam objek supaya langkah-langkahnya dirangkai dan terbaca dari atas ke bawah, bukan fungsi array bersarang yang dibaca dari dalam. Di Laravel, collect($array) membuatnya: filter() menyaring, map() mengubah, pluck() mengambil satu kolom, groupBy() mengelompokkan, sum() menjumlahkan (collect([10, 20, 30])->sum() = 60), last() mengambil yang terakhir, dan echo mencetaknya sebagai JSON. filter() mempertahankan key ({"3":4,"4":5}), jadi tambahkan values(). PHP modern memasangkan enum backed (enum Hari: string { case Senin = "senin"; ... }, boleh punya method) dengan match yang punya default untuk case yang gak disebut.