Sebagian besar data di PHP hidup dalam bentuk array: daftar produk, baris pesanan, sampai konfigurasi aplikasi. Perulangan seperti while dan for mengharuskan kita mengelola counter dan indeks secara manual, padahal yang sebenarnya kita butuhkan hanyalah “proses setiap elemen”. PHP menyediakan foreach khusus untuk kebutuhan tersebut. Struktur ini membaca isi array atau object secara langsung tanpa counter, sehingga kode menjadi lebih pendek dan terhindar dari bug batas indeks (off-by-one). Pada chapter ini kita akan mempelajari seluruh bentuk foreach, mulai dari penelusuran nilai sederhana sampai destructuring dan iterasi dengan referensi.
Bentuk Dasar foreach #
Bentuk paling sederhana dari foreach mengambil satu elemen pada satu waktu dari array, mengikat nilainya ke sebuah variabel, lalu menjalankan blok kode untuk elemen tersebut. Kita tidak perlu tahu posisi elemen dan tidak perlu menghitung berapa banyak elemen yang ada. Mari kita lihat wujudnya dalam kode:
<?php
$buah = ["Apel", "Jeruk", "Pisang"];
foreach ($buah as $item) {
echo "Buah: $item\n";
}Output yang Dihasilkan:
Buah: Apel
Buah: Jeruk
Buah: PisangMari kita telaah apa yang terjadi pada baris-baris kode di atas:
- Baris 2: array
$buahdidefinisikan dengan tiga elemen string berindeks0,1, dan2. - Baris 4: foreach mengambil elemen pertama (
"Apel") dan mengikat nilainya ke variabel$item. - Baris 5:
echomencetak nilai$itemuntuk iterasi yang sedang berjalan, lalu blok selesai dan foreach maju ke elemen berikutnya. - Setelah elemen terakhir (
"Pisang") diproses, foreach berhenti dengan sendirinya tanpa perlu counter atau kondisi tambahan.
Bentuk ini paling cocok untuk array terindeks yang hanya membutuhkan nilainya. Karena kita tidak pernah menyentuh indeks, kesalahan umum seperti mengakses $buah[3] yang tidak ada tidak akan pernah terjadi.
Menelusuri Key dan Nilai #
Array asosiatif menyimpan pasangan key dan nilai — misalnya nama produk sebagai key dan jumlah stok sebagai nilai. foreach menyediakan bentuk kedua yang mengambil keduanya sekaligus, seperti yang telah kita kenal sekilas pada pembahasan tipe data array. Perhatikan contoh berikut:
<?php
$stok = [
"Apel" => 12,
"Jeruk" => 7,
"Pisang" => 25,
];
foreach ($stok as $nama => $jumlah) {
echo "$nama: $jumlah buah\n";
}Output yang Dihasilkan:
Apel: 12 buah
Jeruk: 7 buah
Pisang: 25 buahPada setiap iterasi, interpreter mengambil satu pasangan key => nilai dari array, menempatkan key-nya ke $nama dan nilainya ke $jumlah. Urutan penelusuran mengikuti urutan penyisipan elemen ke dalam array, bukan urutan alfabetis key-nya. Bentuk $kunci => $nilai semacam ini adalah cara paling idiomatik menelusuri array asosiatif di PHP.
Mengubah Elemen dengan Referensi #
Secara bawaan, variabel di header foreach berisi salinan nilai — bukan tampilan langsung ke elemen array. Jika kita menulis $item = ... di dalam loop, perubahan tersebut tidak menyentuh array asal. Untuk benar-benar mengubah isi array, tambahkan tanda & sebelum nama variabel:
<?php
$harga = [5000, 12000, 7500];
foreach ($harga as &$hargaItem) {
$hargaItem = $hargaItem * 2;
}
unset($hargaItem);
echo "Harga baru: " . implode(", ", $harga) . "\n";Output yang Dihasilkan:
Harga baru: 10000, 24000, 15000Mari kita bedah baris-baris pentingnya:
- Baris 4 (
foreach ($harga as &$hargaItem)): tanda&menjadikan$hargaItemsebuah referensi — alias langsung ke elemen array yang sedang ditelusuri, bukan salinannya. - Baris 5 (
$hargaItem = $hargaItem * 2;): penugasan ini menimpa elemen asli di dalam$harga, bukan variabel sementara. - Baris 7 (
unset($hargaItem);): melepas status referensi setelah loop selesai — kebiasaan yang sangat penting, dijelaskan pada peringatan di bawah. - Baris 9:
implode()menggabungkan array menjadi satu string untuk membuktikan seluruh elemen berubah nilainya.
foreach Bersarang untuk Array Multidimensi #
Data nyata sering berbentuk array di dalam array — misalnya menu yang dikelompokkan per kategori. foreach dapat bersarang persis seperti if atau for: loop luar mengambil satu kelompok, loop dalam menelusuri isi kelompok tersebut. Perhatikan contoh berikut:
<?php
$menu = [
"Makanan" => ["Nasi Goreng", "Mie Ayam"],
"Minuman" => ["Es Teh", "Kopi Susu"],
];
foreach ($menu as $kategori => $daftar) {
echo "Kategori $kategori:\n";
foreach ($daftar as $item) {
echo " - $item\n";
}
}Output yang Dihasilkan:
Kategori Makanan:
- Nasi Goreng
- Mie Ayam
Kategori Minuman:
- Es Teh
- Kopi SusuLoop luar menelusuri array asosiatif $menu, sehingga $kategori berisi nama kategori dan $daftar berisi subarray menu. Loop dalam kemudian menelusuri subarray tersebut elemen per elemen. Setiap kombinasi kategori dan item dijamin tercetak tepat satu kali — pola yang nanti kita pakai terus-menerus saat memproses data berbentuk tabel.
Modifikasi Array Saat Iterasi #
Pertanyaan klasik pemula: apa yang terjadi jika kita menambah elemen ke array di tengah penelusurannya? PHP menjawab dengan perilaku yang aman dan terdefinisi — foreach menelusuri salinan struktur internal array yang dibuat saat loop dimulai, sehingga elemen baru tidak ikut diproses pada putaran yang sedang berjalan:
<?php
$angka = [1, 2, 3];
$dilihat = [];
foreach ($angka as $n) {
$dilihat[] = $n;
$angka[] = $n * 10;
}
echo "Iterasi melihat: " . implode(", ", $dilihat) . "\n";
echo "Isi array akhir: " . implode(", ", $angka) . "\n";Output yang Dihasilkan:
Iterasi melihat: 1, 2, 3
Isi array akhir: 1, 2, 3, 10, 20, 30Baris $angka[] = $n * 10; menambah elemen baru pada setiap iterasi, tetapi loop tetap berhenti setelah tiga putaran — persis jumlah elemen saat foreach dimulai. Setelah loop selesai, array sudah memuat enam elemen karena tambahan dari dalam loop tetap tersimpan. Perlu dicatat: jaminan ini berlaku untuk daftar elemen yang ditelusuri, bukan isi elemennya — pada bentuk referensi &$item, perubahan nilai tetap langsung terlihat karena kita menulis ke elemen aslinya. Jika elemen baru memang harus ikut diproses, jalankan iterasi kedua setelah loop pertama selesai.
Destructuring Elemen dengan Pola list() #
Array dua dimensi sering berisi baris berpola tetap, misalnya ["nama", nilai]. Alih-alih mengakses $baris[0] dan $baris[1], foreach dapat membongkar setiap elemen langsung di header menggunakan tanda kurung siku:
<?php
$siswa = [
["Budi", 85],
["Siti", 92],
["Andi", 78],
];
foreach ($siswa as $nomor => [$nama, $nilai]) {
echo "Siswa ke-" . ($nomor + 1) . ": $nama ($nilai)\n";
}Output yang Dihasilkan:
Siswa ke-1: Budi (85)
Siswa ke-2: Siti (92)
Siswa ke-3: Andi (78)Pola [$nama, $nilai] memetakan posisi pertama elemen ke $nama dan posisi kedua ke $nilai — teknik yang disebut destructuring. Bentuk panjangnya memakai kata kunci list(): foreach ($siswa as list($nama, $nilai)), dengan makna yang sama persis. Kombinasi $nomor => [$nama, $nilai] menunjukkan bahwa key dan destructuring nilai bisa dipakai bersamaan, membuat setiap baris data terbaca jelas tanpa indeks manual.
Menelusuri Object dengan foreach #
foreach juga mampu menelusuri property sebuah object, bukan hanya array. Aturannya penting: hanya property public yang terlihat dari luar class. Kita belum membahas class secara mendalam — untuk sekarang, cukup pahami bahwa $nama dan $harga di bawah ini adalah data yang menempel pada sebuah object:
<?php
class Produk
{
public string $nama = "Kopi Torabika";
public int $harga = 15000;
protected int $stok = 40;
}
foreach (new Produk() as $properti => $nilai) {
echo "$properti: $nilai\n";
}Output yang Dihasilkan:
nama: Kopi Torabika
harga: 15000Output hanya menampilkan dua baris karena property $stok diberi tingkat akses protected, sehingga tersembunyi dari penelusuran di luar class. Detail tingkat akses seperti public dan protected akan kita bedah tuntas pada Section Object-Oriented Programming. Untuk kebutuhan sehari-hari, ingat satu hal saja: foreach pada object bekerja seperti foreach pada array asosiatif berisi property yang terlihat.
Memilih antara for dan foreach #
Untuk array terindeks, for dan foreach sama-sama bisa dipakai — namun keduanya tidak setara dalam hal keamanan dan kejelasan. Tabel berikut merangkum pertimbangan praktisnya:
| Aspek | foreach | for |
|---|---|---|
| Counter manual | Tidak perlu | Wajib mengelola $i sendiri |
| Akses key | Bawaan ($kunci => $nilai) | Hanya lewat $array[$i] |
| Risiko salah batas | Praktis nol | Ada (<= versus <) |
| Cocok untuk | Array terindeks maupun asosiatif | Pola numerik: langkah, rentang, mundur |
| Mengubah elemen | Mudah lewat &$item | Lebih bertele-tele via indeks |
Berkas contoh.php pada bagian bawah halaman merangkum seluruh bentuk foreach di atas — dari penelusuran nilai sederhana sampai destructuring dan iterasi object — dalam satu program utuh yang dapat Anda unduh dan jalankan langsung dengan php contoh.php.
Ringkasan #
foreach adalah alat iterasi utama PHP: bentuk nilai untuk array sederhana, $kunci => $nilai untuk array asosiatif, &$item untuk mengubah elemen secara langsung, destructuring [$a, $b] untuk baris berpola, dan penelusuran property public untuk object. foreach juga aman terhadap modifikasi array di tengah iterasi karena menelusuri salinan struktur internal. Kadang kita justru perlu menghentikan atau melewati iterasi sebelum semua elemen selesai diproses — itu pekerjaan break dan continue pada chapter berikutnya.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
contoh.php
Unduh berkas<?php
// contoh.php — rangkuman seluruh bentuk foreach dari chapter "foreach Loops".
// Jalankan dengan: php contoh.php
echo "== Bentuk dasar ==\n";
$buah = ["Apel", "Jeruk", "Pisang"];
foreach ($buah as $item) {
echo "Buah: $item\n";
}
echo "\n== Key dan nilai ==\n";
$stok = [
"Apel" => 12,
"Jeruk" => 7,
"Pisang" => 25,
];
foreach ($stok as $nama => $jumlah) {
echo "$nama: $jumlah buah\n";
}
echo "\n== Mengubah elemen dengan referensi ==\n";
$harga = [5000, 12000, 7500];
foreach ($harga as &$hargaItem) {
$hargaItem = $hargaItem * 2;
}
unset($hargaItem);
echo "Harga baru: " . implode(", ", $harga) . "\n";
echo "\n== foreach bersarang ==\n";
$menu = [
"Makanan" => ["Nasi Goreng", "Mie Ayam"],
"Minuman" => ["Es Teh", "Kopi Susu"],
];
foreach ($menu as $kategori => $daftar) {
echo "Kategori $kategori:\n";
foreach ($daftar as $item) {
echo " - $item\n";
}
}
echo "\n== Modifikasi array saat iterasi ==\n";
$angka = [1, 2, 3];
$dilihat = [];
foreach ($angka as $n) {
$dilihat[] = $n;
$angka[] = $n * 10;
}
echo "Iterasi melihat: " . implode(", ", $dilihat) . "\n";
echo "Isi array akhir: " . implode(", ", $angka) . "\n";
echo "\n== Destructuring elemen ==\n";
$siswa = [
["Budi", 85],
["Siti", 92],
["Andi", 78],
];
foreach ($siswa as $nomor => [$nama, $nilai]) {
echo "Siswa ke-" . ($nomor + 1) . ": $nama ($nilai)\n";
}
echo "\n== Menelusuri object ==\n";
class Produk
{
public string $nama = "Kopi Torabika";
public int $harga = 15000;
protected int $stok = 40;
}
foreach (new Produk() as $properti => $nilai) {
echo "$properti: $nilai\n";
}