Operator perbandingan biasa menjawab satu pertanyaan saja: < menjawab “lebih kecil?”, == menjawab “sama?”. Namun banyak algoritma — terutama pengurutan — butuh ketiganya sekaligus: lebih kecil, sama, atau lebih besar. Sebelum PHP 7, kita menulis tiga perbandingan berturut-turut; kini cukup satu operator: spaceship (<=>), yang mengembalikan -1, 0, atau 1 sesuai posisi kedua nilai. Pada Chapter ini kita akan mempelajari semantik spaceship pada angka, string, dan array, lalu memakainya untuk mengurutkan data dengan fungsi usort().
Perbandingan Tiga Arah #
Spaceship operator mengevaluasi $a <=> $b dengan hasil pasti salah satu dari tiga nilai integer:
<?php
var_dump(5 <=> 3);
var_dump(3 <=> 5);
var_dump(5 <=> 5);
var_dump(1.5 <=> 1.7);
var_dump(true <=> false);Output yang Dihasilkan:
int(1)
int(-1)
int(0)
int(-1)
int(1)Aturannya ringkas: -1 bila operand kiri lebih kecil, 1 bila lebih besar, dan 0 bila keduanya setara. Ketiga hasil ini sengaja dipilih agar cocok dengan konvensi three-way comparison yang sudah lama dipakai fungsi pembanding di banyak bahasa pemrograman — nanti kita lihat bahwa usort() memang berharap tepat nilai-nilai ini. Perhatikan bahwa spaceship juga membandingkan float dan boolean dengan aturan perbandingan PHP yang sama seperti operator < dan >.
Membandingkan String #
Untuk string, spaceship mengikuti aturan perbandingan standar PHP: jika kedua string adalah string numerik (seperti "10" dan "9"), keduanya dibandingkan sebagai angka; jika tidak, perbandingan dilakukan per karakter dari kiri:
<?php
var_dump("apel" <=> "jeruk");
var_dump("a" <=> "A");
var_dump("10" <=> "9");
var_dump("2" <=> "10");
var_dump(10 <=> 9);Output yang Dihasilkan:
int(-1)
int(1)
int(1)
int(-1)
int(1)Perhatikan ketiga baris terakhir dengan saksama — inilah sumber kejutan klasik. "10" <=> "9" menghasilkan 1 karena keduanya string numerik sehingga dibandingkan sebagai angka (10 > 9), hasil yang sama dengan 10 <=> 9. Sementara "apel" <=> "jeruk" dan "a" <=> "A" membandingkan kode karakter: huruf pertama a (kode 97) lebih kecil dari j, dan lebih besar dari A besar (kode 65) — itulah mengapa hasilnya -1 lalu 1. Campuran "2" <=> "10" kembali numerik (2 < 10).
Membandingkan Array #
Array dibandingkan element demi element dari kiri; bila semua element awal setara, array yang lebih pendek dianggap lebih kecil:
<?php
var_dump([1, 2, 3] <=> [1, 2, 3]);
var_dump([1, 2, 4] <=> [1, 2, 3]);
var_dump([1, 2] <=> [1, 2, 0]);Output yang Dihasilkan:
int(0)
int(1)
int(-1)Baris pertama menghasilkan 0 karena semua element setara. Baris kedua menemukan perbedaan di element ketiga (4 vs 3) sehingga menghasilkan 1. Baris ketiga memperlihatkan aturan panjang: element yang ada semuanya setara, maka array dengan dua element kalah dari array dengan tiga element. Aturan ini identik dengan perilaku operator < dan > pada array — spaceship hanya membungkusnya menjadi satu hasil.
Dari Tiga Operator Menjadi Satu #
Nilai usort()-friendly inilah alasan utama spaceship lahir. Sebelum PHP 7, fungsi pembanding harus menulis tiga cabang secara manual:
<?php
function bandingkanCaraLama(int $a, int $b): int {
if ($a < $b) {
return -1;
}
if ($a > $b) {
return 1;
}
return 0;
}
function bandingkanCaraBaru(int $a, int $b): int {
return $a <=> $b;
}
echo bandingkanCaraLama(3, 7) . bandingkanCaraLama(7, 3) . bandingkanCaraLama(7, 7) . "\n";
echo bandingkanCaraBaru(3, 7) . bandingkanCaraBaru(7, 3) . bandingkanCaraBaru(7, 7) . "\n";Output yang Dihasilkan:
-110
-110Kedua baris keluaran identik: string -110 adalah perangkaian tiga hasil terpisah (-1, lalu 1, lalu 0). Perbedaannya ada pada jumlah kode: versi baru hanya membutuhkan satu baris logika. (Fungsi sendiri baru dibahas tuntas pada Section Fungsi; di sini cukup pahami bahwa bandingkanCaraLama dan bandingkanCaraBaru menerima dua angka dan mengembalikan -1, 0, atau 1.)
Praktik dengan usort #
Fungsi bawaan usort(array &$array, callable $callback) mengurutkan array dengan memanggil $callback berulang kali untuk membandingkan dua element; usort() membaca nilai kembaliannya persis seperti hasil spaceship. Contoh berikut mengurutkan daftar produk dari harga termurah:
<?php
$produk = [
["nama" => "Monitor", "harga" => 1500000],
["nama" => "Keyboard", "harga" => 350000],
["nama" => "Laptop", "harga" => 8500000],
];
usort($produk, function ($a, $b) {
return $a["harga"] <=> $b["harga"];
});
foreach ($produk as $item) {
echo $item["nama"] . ": Rp" . $item["harga"] . "\n";
}Output yang Dihasilkan:
Keyboard: Rp350000
Monitor: Rp1500000
Laptop: Rp8500000Mari kita bedah cara kerjanya:
- Argumen pertama (
$produk): array yang ingin diurutkan, dikirim sebagai referensi sehingga perubahan langsung berlaku pada variabel aslinya. - Argumen kedua (
function ($a, $b) { ... }): callback — fungsi tanpa nama yang dipanggilusort()setiap kali butuh membandingkan dua element. - Isi callback (
$a["harga"] <=> $b["harga"]): hasil-1memberi tahuusort()bahwa$aharus berdiri sebelum$b;1sebaliknya;0berarti urutannya bebas.
Mengurutkan dari harga termahal kini hanya soal menukar posisi operand: return $b["harga"] <=> $a["harga"]; — kebalikan arah perbandingan membalik arah urutan. (Struktur foreach untuk mencetak hasilnya dibahas tuntas pada Section Control Flow; usort() sendiri dibahas lebih jauh pada Section Arrays dan Collections.)
Berkas contoh.php pada bagian bawah halaman mendemonstrasikan pengurutan naik dan turun sekaligus dalam satu program utuh.
Ringkasan #
Spaceship operator $a <=> $b menghasilkan -1, 0, atau 1 dalam satu ekspresi — ringkasan dari <, ==, dan > sekaligus. Perbandingannya mengikuti aturan standar PHP: string numerik dibandingkan sebagai angka, array dibandingkan element demi element, dan hasilnya selalu salah satu dari tiga integer itu. Kombinasi <=> dengan usort() mengubah tiga cabang if menjadi satu baris. Selanjutnya kita pelajari operator yang mengubah nilai dengan efek samping pada variabelnya sendiri: increment dan decrement.
Referensi #
- Dokumentasi operator perbandingan (spaceship) — php.net
- Fungsi usort() — php.net
- Fitur baru PHP 7.0 (spaceship operator) — php.net
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
contoh.php
Unduh berkas<?php
// contoh.php — rangkuman Spaceship Operator
// Jalankan dengan: php contoh.php
// 1. Perbandingan tiga arah pada angka
echo "5 <=> 3 : ", var_export(5 <=> 3, true), "\n";
echo "3 <=> 5 : ", var_export(3 <=> 5, true), "\n";
echo "5 <=> 5 : ", var_export(5 <=> 5, true), "\n";
// 2. String numerik dibandingkan sebagai angka, string biasa per karakter
echo "\"10\" <=> \"9\" : ", var_export("10" <=> "9", true), "\n";
echo "\"apel\" <=> \"jeruk\" : ", var_export("apel" <=> "jeruk", true), "\n";
// 3. Array: element demi element, lalu panjang
echo "[1,2] <=> [1,2,0] : ", var_export([1, 2] <=> [1, 2, 0], true), "\n";
// 4. Pengurutan naik dan turun dengan usort + spaceship
$produk = [
["nama" => "Monitor", "harga" => 1500000],
["nama" => "Keyboard", "harga" => 350000],
["nama" => "Laptop", "harga" => 8500000],
];
usort($produk, function ($a, $b) {
return $a["harga"] <=> $b["harga"];
});
echo "Termurah dulu:\n";
foreach ($produk as $item) {
echo " {$item['nama']}: Rp{$item['harga']}\n";
}
usort($produk, function ($a, $b) {
return $b["harga"] <=> $a["harga"];
});
echo "Termahal dulu:\n";
foreach ($produk as $item) {
echo " {$item['nama']}: Rp{$item['harga']}\n";
}