Array #
Array PHP adalah struktur data yang jauh lebih fleksibel dari yang terlihat di permukaan. Di baliknya, semua array PHP adalah ordered map — peta yang mempertahankan urutan insertion, mendukung key integer maupun string dalam satu array yang sama, dan bisa berfungsi sebagai list, dictionary, stack, queue, atau bahkan set sekaligus tergantung cara memakainya. PHP memiliki lebih dari 70 fungsi bawaan khusus untuk array — tapi tidak semua perlu dihapal. Yang penting adalah menguasai pola-pola yang paling sering muncul: transformasi dengan array_map, filter dengan array_filter, agregasi dengan array_reduce, sorting dengan usort, dan pengambilan kolom dengan array_column. Artikel ini membahas semua aspek array PHP secara mendalam beserta pola-pola idiomatik yang membuat kode lebih bersih dari loop eksplisit.
Mendefinisikan Array #
PHP mendukung dua sintaks untuk membuat array: array() yang klasik dan [] yang modern dan ringkas. Gunakan [] untuk semua kode baru.
<?php
// Sintaks modern (PHP 5.4+) — gunakan ini
$kosong = [];
$terindeks = [1, 2, 3, 4, 5];
$asosiatif = ['nama' => 'Budi', 'umur' => 28, 'kota' => 'Jakarta'];
$campuran = [0 => 'nol', 'satu' => 1, 2 => 'dua']; // valid tapi hindari
// Sintaks lama — masih valid, tapi tidak idiomatik
$terindeksLama = array(1, 2, 3);
$asosiatifLama = array('nama' => 'Budi', 'umur' => 28);
// Array multidimensi
$tabel = [
['id' => 1, 'nama' => 'Laptop', 'harga' => 15_000_000, 'stok' => 5],
['id' => 2, 'nama' => 'Monitor', 'harga' => 5_000_000, 'stok' => 12],
['id' => 3, 'nama' => 'Mouse', 'harga' => 250_000, 'stok' => 0],
['id' => 4, 'nama' => 'Keyboard','harga' => 800_000, 'stok' => 8],
];
// Akses elemen
echo $terindeks[0]; // 1
echo $asosiatif['nama']; // Budi
echo $tabel[1]['nama']; // Monitor
echo $tabel[0]['harga']; // 15000000
Array adalah Ordered Map #
PHP array bukan sekadar list — setiap elemen memiliki key yang bisa berupa integer atau string. Memahami ini penting karena unset() tidak mereset indeks:
<?php
$a = ['apel', 'mangga', 'jeruk', 'anggur'];
// Key: 0 1 2 3
unset($a[1]); // hapus 'mangga'
print_r($a);
// Array ( [0] => apel [2] => jeruk [3] => anggur )
// Indeks 1 HILANG — tidak di-reindex otomatis!
// Untuk reindex setelah unset, gunakan array_values()
$a = array_values($a);
print_r($a);
// Array ( [0] => apel [1] => jeruk [2] => anggur )
Menambah, Mengubah, dan Menghapus Elemen #
<?php
$buah = ['apel', 'mangga'];
// Tambah di akhir
$buah[] = 'jeruk'; // indeks otomatis — sekarang [0,1,2]
$buah[] = 'anggur';
array_push($buah, 'semangka'); // sama dengan $buah[] = 'semangka'
// Tambah di awal
array_unshift($buah, 'alpukat'); // [alpukat, apel, mangga, jeruk, anggur, semangka]
// Hapus dari akhir — mengembalikan elemen yang dihapus
$terakhir = array_pop($buah); // 'semangka'
// Hapus dari awal — mengembalikan elemen yang dihapus
$pertama = array_shift($buah); // 'alpukat'
// Hapus elemen tertentu
unset($buah[2]); // indeks 2 hilang, tidak di-reindex
// Ubah nilai
$buah[0] = 'apel merah'; // override elemen pertama
// Sisipkan di posisi tertentu dengan array_splice()
// array_splice($array, $offset, $panjangDihapus, $sisipan)
array_splice($buah, 1, 0, ['kiwi', 'lemon']); // sisipkan di indeks 1 tanpa hapus
Mengakses Elemen dengan Aman #
<?php
$config = ['host' => 'localhost', 'port' => 3306, 'debug' => false];
// Akses langsung — error jika key tidak ada
echo $config['host']; // localhost
// Null coalescing — aman untuk key yang mungkin tidak ada
echo $config['user'] ?? 'root'; // 'root' — key tidak ada
echo $config['debug'] ?? true; // false — key ada, nilainya false
echo $config['timeout'] ?? 30; // 30 — key tidak ada
// array_key_exists — bedakan antara key tidak ada vs nilai null
$data = ['nama' => null];
var_dump(isset($data['nama'])); // false — null dianggap tidak ada oleh isset
var_dump(array_key_exists('nama', $data)); // true — key ada meski nilainya null
// Akses nested yang aman
$user = ['profil' => ['kota' => 'Jakarta']];
echo $user['profil']['kota'] ?? 'Tidak diketahui'; // Jakarta
echo $user['profil']['negara'] ?? 'Indonesia'; // Indonesia — key tidak ada
echo $user['alamat']['kota'] ?? 'Tidak diketahui'; // Tidak diketahui
Transformasi Array #
Fungsi transformasi menghasilkan array baru tanpa mengubah array aslinya — ini adalah pola yang lebih bersih dari loop eksplisit dengan append.
array_map — Ubah Setiap Elemen
#
<?php
$harga = [10000, 25000, 50000, 100000];
// Tambah PPN 11% ke setiap harga
$hargaPpn = array_map(fn($h) => $h * 1.11, $harga);
// [11100, 27750, 55500, 111000]
// Konversi format
$formatRupiah = array_map(
fn($h) => 'Rp ' . number_format($h, 0, ',', '.'),
$harga
);
// ['Rp 10.000', 'Rp 25.000', 'Rp 50.000', 'Rp 100.000']
// array_map dengan beberapa array — diiterasi paralel
$nama = ['Budi', 'Siti', 'Dani'];
$nilai = [85, 92, 78];
$laporan = array_map(
fn($n, $v) => ['nama' => $n, 'nilai' => $v, 'lulus' => $v >= 70],
$nama,
$nilai
);
// [['nama'=>'Budi','nilai'=>85,'lulus'=>true], ...]
// First-class callable — lebih bersih untuk fungsi yang sudah ada
$kata = [' halo ', ' DUNIA ', ' php '];
$bersih = array_map(trim(...), $kata); // trim setiap elemen
$hurufKecil = array_map(strtolower(...), $bersih); // lowercase
array_filter — Pilih Elemen Berdasarkan Kondisi
#
<?php
$produk = [
['nama' => 'Laptop', 'harga' => 15_000_000, 'stok' => 5],
['nama' => 'Monitor', 'harga' => 5_000_000, 'stok' => 0],
['nama' => 'Mouse', 'harga' => 250_000, 'stok' => 20],
['nama' => 'Keyboard','harga' => 800_000, 'stok' => 0],
];
// Filter produk yang tersedia (stok > 0)
$tersedia = array_filter($produk, fn($p) => $p['stok'] > 0);
// Laptop dan Mouse
// Filter produk mahal (harga > 1 juta)
$mahal = array_filter($produk, fn($p) => $p['harga'] > 1_000_000);
// Laptop dan Monitor
// Tanpa callback — hapus nilai falsy (false, 0, "", null, [])
$data = [1, 0, 'halo', '', null, false, 2, [], 3];
$bersih = array_filter($data);
// [0=>1, 2=>'halo', 6=>2, 8=>3] — indeks DIPERTAHANKAN
// Reindex setelah filter jika diperlukan
$bersih = array_values(array_filter($data));
// [0=>1, 1=>'halo', 2=>2, 3=>3]
// ANTI-PATTERN: loop eksplisit untuk filter sederhana
$hasil = [];
foreach ($produk as $p) {
if ($p['stok'] > 0) {
$hasil[] = $p;
}
}
// BENAR: array_filter lebih ekspresif
$hasil = array_values(array_filter($produk, fn($p) => $p['stok'] > 0));
array_reduce — Agregasi ke Satu Nilai
#
<?php
$items = [
['nama' => 'Laptop', 'harga' => 15_000_000, 'qty' => 1],
['nama' => 'Mouse', 'harga' => 250_000, 'qty' => 2],
['nama' => 'Monitor', 'harga' => 5_000_000, 'qty' => 1],
];
// Hitung total belanja
$total = array_reduce(
$items,
fn($carry, $item) => $carry + ($item['harga'] * $item['qty']),
0 // nilai awal
);
// 15_000_000 + 500_000 + 5_000_000 = 20_500_000
// Buat lookup table dari array
$lookup = array_reduce(
$items,
fn($carry, $item) => array_merge($carry, [$item['nama'] => $item['harga']]),
[]
);
// ['Laptop' => 15000000, 'Mouse' => 250000, 'Monitor' => 5000000]
// Lebih efisien dengan spread
$lookup = array_reduce(
$items,
fn($carry, $item) => [...$carry, $item['nama'] => $item['harga']],
[]
);
Pipeline: Gabungkan map + filter + reduce #
<?php
$orders = [
['id' => 1, 'total' => 150_000, 'status' => 'selesai', 'diskon' => 0],
['id' => 2, 'total' => 800_000, 'status' => 'batal', 'diskon' => 0.1],
['id' => 3, 'total' => 2_500_000,'status' => 'selesai', 'diskon' => 0.15],
['id' => 4, 'total' => 300_000, 'status' => 'selesai', 'diskon' => 0],
['id' => 5, 'total' => 900_000, 'status' => 'proses', 'diskon' => 0.05],
];
// Pipeline: filter selesai → hitung setelah diskon → jumlahkan
$pendapatanBersih = array_reduce(
array_map(
fn($o) => $o['total'] * (1 - $o['diskon']), // step 2: hitung net
array_filter($orders, fn($o) => $o['status'] === 'selesai') // step 1: filter
),
fn($carry, $net) => $carry + $net, // step 3: jumlahkan
0
);
// (150000 * 1) + (2500000 * 0.85) + (300000 * 1) = 2_675_000
array_column — Ambil Kolom dari Array Multidimensi
#
array_column adalah salah satu fungsi array paling berguna yang sering diabaikan:
<?php
$users = [
['id' => 1, 'nama' => 'Budi', 'email' => '[email protected]', 'role' => 'admin'],
['id' => 2, 'nama' => 'Siti', 'email' => '[email protected]', 'role' => 'editor'],
['id' => 3, 'nama' => 'Dani', 'email' => '[email protected]', 'role' => 'viewer'],
['id' => 4, 'nama' => 'Rina', 'email' => '[email protected]', 'role' => 'editor'],
];
// Ambil satu kolom sebagai array flat
$semuaNama = array_column($users, 'nama');
// ['Budi', 'Siti', 'Dani', 'Rina']
$semuaEmail = array_column($users, 'email');
// ['[email protected]', '[email protected]', ...]
// Ambil kolom dengan key dari kolom lain (buat lookup table)
$emailById = array_column($users, 'email', 'id');
// [1 => '[email protected]', 2 => '[email protected]', ...]
$userByEmail = array_column($users, null, 'email');
// ['[email protected]' => ['id'=>1,'nama'=>'Budi',...], ...]
// Contoh praktis: cari user by ID dengan O(1)
$userById = array_column($users, null, 'id');
$user = $userById[2] ?? null; // langsung tanpa loop
// Grouping dengan array_reduce + array_column
$byRole = array_reduce(
$users,
function($carry, $user) {
$carry[$user['role']][] = $user;
return $carry;
},
[]
);
// ['admin' => [...], 'editor' => [..., ...], 'viewer' => [...]]
Sorting #
PHP menyediakan banyak fungsi sorting. Memilih yang tepat penting karena hasilnya bisa berbeda secara signifikan.
Sorting Dasar #
<?php
$angka = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
// sort() — ascending, RESET key
sort($angka); // [1,1,2,3,3,4,5,5,6,9]
// rsort() — descending, RESET key
rsort($angka); // [9,6,5,5,4,3,3,2,1,1]
// asort() — ascending, PERTAHANKAN key (untuk asosiatif)
$nilai = ['Budi' => 85, 'Siti' => 92, 'Dani' => 78];
asort($nilai);
// ['Dani' => 78, 'Budi' => 85, 'Siti' => 92]
// arsort() — descending, pertahankan key
arsort($nilai);
// ['Siti' => 92, 'Budi' => 85, 'Dani' => 78]
// ksort() — sort by KEY ascending
ksort($nilai);
// ['Budi' => 85, 'Dani' => 78, 'Siti' => 92]
// krsort() — sort by KEY descending
krsort($nilai);
usort — Sorting dengan Kriteria Kustom
#
<?php
$produk = [
['nama' => 'Laptop', 'harga' => 15_000_000, 'rating' => 4.5],
['nama' => 'Monitor', 'harga' => 5_000_000, 'rating' => 4.2],
['nama' => 'Mouse', 'harga' => 250_000, 'rating' => 4.8],
['nama' => 'Keyboard','harga' => 800_000, 'rating' => 4.1],
];
// Sort by harga ascending
usort($produk, fn($a, $b) => $a['harga'] <=> $b['harga']);
// Sort by harga descending
usort($produk, fn($a, $b) => $b['harga'] <=> $a['harga']);
// Sort by rating descending, lalu nama ascending jika rating sama
usort($produk, fn($a, $b)
=> [$b['rating'], $a['nama']] <=> [$a['rating'], $b['nama']]
);
// Array comparison element-by-element — teknik sorting tuple yang elegan
// uasort() — seperti usort tapi pertahankan key
$ratings = ['Laptop' => 4.5, 'Monitor' => 4.2, 'Mouse' => 4.8];
uasort($ratings, fn($a, $b) => $b <=> $a); // descending, key dipertahankan
// uksort() — sort by key dengan komparator kustom
uksort($ratings, fn($a, $b) => strlen($a) <=> strlen($b)); // sort by panjang nama
Natural Sort — Sorting String yang Mengandung Angka #
<?php
$file = ['file10.txt', 'file2.txt', 'file1.txt', 'file20.txt'];
sort($file);
// ['file1.txt', 'file10.txt', 'file2.txt', 'file20.txt'] — string sort, 10 < 2 :(
natsort($file);
// ['file1.txt', 'file2.txt', 'file10.txt', 'file20.txt'] — natural, benar!
natcasesort($file); // seperti natsort tapi case-insensitive
Pencarian dan Pemeriksaan #
<?php
$buah = ['apel', 'mangga', 'jeruk', 'anggur', 'mangga'];
// Periksa apakah nilai ada
var_dump(in_array('jeruk', $buah)); // true
var_dump(in_array('semangka', $buah)); // false
var_dump(in_array('0', [false, null, ''])); // true! — gunakan strict mode
// Strict mode — perbandingan ===
var_dump(in_array('0', [false, null, ''], true)); // false — strict
// Cari indeks/key dari nilai
$indeks = array_search('mangga', $buah); // 1 (pertama yang ditemukan)
var_dump(array_search('semangka', $buah)); // false — tidak ada
// Periksa apakah key ada
var_dump(array_key_exists('nama', ['nama' => null, 'umur' => 28])); // true
var_dump(isset(['nama' => null]['nama'])); // false!
// Dapatkan semua key atau semua value
$assoc = ['a' => 1, 'b' => 2, 'c' => 3];
$keys = array_keys($assoc); // ['a', 'b', 'c']
$values = array_values($assoc); // [1, 2, 3]
// array_keys dengan filter nilai — cari semua key dengan nilai tertentu
$duplikat = ['apel', 'mangga', 'jeruk', 'mangga', 'apel'];
$keyMangga = array_keys($duplikat, 'mangga'); // [1, 3]
Penggabungan dan Pemisahan #
<?php
// array_merge — key string dari kanan override kiri
$default = ['timeout' => 30, 'retry' => 3, 'debug' => false];
$custom = ['timeout' => 10, 'host' => 'api.example.com'];
$config = array_merge($default, $custom);
// ['timeout'=>10, 'retry'=>3, 'debug'=>false, 'host'=>'api.example.com']
// Spread operator — seperti merge tapi lebih ringkas
$config2 = [...$default, ...$custom];
// Hasil identik dengan array_merge untuk array non-integer key
// PERHATIAN: array_merge vs + (union)
$a = ['x' => 1, 'y' => 2];
$b = ['y' => 9, 'z' => 3];
print_r(array_merge($a, $b)); // y => 9 (kanan menang)
print_r($a + $b); // y => 1 (kiri menang!)
// array_slice — ambil potongan array
$angka = [10, 20, 30, 40, 50, 60];
$potongan = array_slice($angka, 1, 3); // [20, 30, 40]
$akhir = array_slice($angka, -2); // [50, 60]
$denganKey= array_slice($angka, 1, 3, true); // [1=>20, 2=>30, 3=>40]
// array_chunk — bagi array ke beberapa bagian
$data = range(1, 10);
$batch = array_chunk($data, 3);
// [[1,2,3], [4,5,6], [7,8,9], [10]]
$batchDenganKey = array_chunk($data, 3, true); // pertahankan key
// array_combine — gabungkan dua array jadi key-value
$nama = ['Budi', 'Siti', 'Dani'];
$skor = [85, 92, 78];
$hasil = array_combine($nama, $skor);
// ['Budi' => 85, 'Siti' => 92, 'Dani' => 78]
Operasi Set — Unik, Interseksi, Perbedaan #
<?php
$a = [1, 2, 3, 4, 5];
$b = [3, 4, 5, 6, 7];
// Elemen unik dari $a yang tidak ada di $b (difference)
$hanyaDiA = array_diff($a, $b); // [0=>1, 1=>2]
// Elemen unik dari $b yang tidak ada di $a
$hanyaDiB = array_diff($b, $a); // [3=>6, 4=>7]
// Elemen yang ada di keduanya (intersection)
$keduanya = array_intersect($a, $b); // [2=>3, 3=>4, 4=>5]
// Hapus duplikat
$duplikat = [1, 2, 2, 3, 3, 3, 4];
$unik = array_unique($duplikat); // [0=>1, 1=>2, 3=>3, 6=>4]
$unikReindex = array_values(array_unique($duplikat)); // [1,2,3,4]
// Operasi pada array asosiatif
$profil1 = ['nama' => 'Budi', 'kota' => 'Jakarta', 'umur' => 28];
$profil2 = ['nama' => 'Budi', 'kota' => 'Bandung', 'hobi' => 'coding'];
$bedaNilai = array_diff_assoc($profil1, $profil2); // ['kota'=>'Jakarta']
$bedaKey = array_diff_key($profil1, $profil2); // ['umur'=>28]
$samaNilaiKey = array_intersect_assoc($profil1, $profil2); // ['nama'=>'Budi']
Array sebagai Stack dan Queue #
<?php
// Stack — LIFO (Last In, First Out)
$stack = [];
array_push($stack, 'pertama'); // atau: $stack[] = 'pertama'
array_push($stack, 'kedua');
array_push($stack, 'ketiga');
$top = array_pop($stack); // 'ketiga' — ambil dari atas
echo array_pop($stack); // 'kedua'
// Queue — FIFO (First In, First Out)
$queue = [];
array_push($queue, 'antrian1');
array_push($queue, 'antrian2');
array_push($queue, 'antrian3');
$depan = array_shift($queue); // 'antrian1' — ambil dari depan (FIFO)
// Deque — Double-ended queue
$deque = ['tengah'];
array_unshift($deque, 'depan'); // tambah ke depan
array_push($deque, 'belakang'); // tambah ke belakang
$dari_depan = array_shift($deque); // ambil dari depan
$dari_belakang = array_pop($deque); // ambil dari belakang
Fungsi Matematika pada Array #
<?php
$data = [5, 3, 8, 1, 9, 2, 7, 4, 6];
echo min($data); // 1
echo max($data); // 9
echo array_sum($data); // 45
echo array_product($data); // 362880 (5 × 3 × 8 × 1 × ... × 6)
// Rata-rata
$rata = array_sum($data) / count($data); // 5
// Fungsi matematika lanjutan (butuh array terurut)
sort($data);
$median = $data[intdiv(count($data), 2)]; // elemen tengah
// array_fill dan array_fill_keys
$defaultStok = array_fill(0, 5, 0); // [0,0,0,0,0] — 5 nol mulai indeks 0
$defaultConfig = array_fill_keys(
['debug', 'cache', 'log'],
false
); // ['debug'=>false, 'cache'=>false, 'log'=>false]
// range() — buat array berurutan
$angka1to10 = range(1, 10); // [1,2,3,4,5,6,7,8,9,10]
$genap = range(0, 20, 2); // [0,2,4,6,8,10,12,14,16,18,20]
$huruf = range('a', 'f'); // ['a','b','c','d','e','f']
array_walk dan array_map — Kapan Mana
#
<?php
$harga = ['laptop' => 15_000_000, 'mouse' => 250_000, 'monitor' => 5_000_000];
// array_map — hasilkan array BARU, tidak ubah asli
$hargaPpn = array_map(fn($h) => $h * 1.11, $harga);
// $harga tidak berubah
// array_walk — modifikasi array IN-PLACE via referensi
// Callback menerima: &$nilai, $key, $data_tambahan (opsional)
array_walk($harga, function(&$nilai, $key) {
$nilai = $nilai * 1.11;
}); // $harga sekarang berisi harga + PPN
// array_walk_recursive — traversal array multidimensi
$nested = ['a' => [1, 2], 'b' => [3, 4], 'c' => 5];
array_walk_recursive($nested, function(&$nilai) {
$nilai *= 2;
});
// ['a' => [2, 4], 'b' => [6, 8], 'c' => 10]
Ringkasan #
- Semua array PHP adalah ordered map — mempertahankan urutan insertion, mendukung key integer dan string.
unset()tidak mereset indeks — gunakanarray_values()untuk reindex.array_mapuntuk transformasi (hasilkan array baru),array_filteruntuk seleksi (pertahankan sebagian elemen),array_reduceuntuk agregasi (jadikan satu nilai) — kombinasi ketiganya membentuk pipeline data yang ekspresif.array_columnadalah cara paling ringkas mengekstrak kolom dari array multidimensi, dan dengan argumen ketiga bisa membangun lookup table[key => row]untuk pencarian O(1).usort+ spaceship operator<=>adalah cara idiomatik sorting dengan kriteria kustom. Untuk multi-kriteria, bandingkan array secara langsung:[$a['harga'], $a['nama']] <=> [$b['harga'], $b['nama']].in_arraydengan strict mode (truesebagai argumen ketiga) mencegah konversi tipe yang tidak diinginkan sepertiin_array('0', [false])yang menghasilkantruetanpa strict.array_mergevs+(union) — perbedaan kritis:array_mergemembiarkan key dari kanan menang untuk key string;+mempertahankan key dari kiri. Untuk numeric key,array_mergemereset indeks,+tidak.- Spread operator
[...$a, ...$b]adalah alternatif modernarray_mergeyang lebih ringkas dan bisa digunakan langsung dalam ekspresi.array_uniquediikutiarray_values— untuk mendapatkan array unik dengan indeks yang bersih.array_uniquesendiri mempertahankan key asli yang bisa berlubang.