Operator

Operator #

Operator adalah simbol yang memerintahkan PHP untuk melakukan operasi tertentu pada satu atau beberapa nilai. PHP memiliki lebih dari dua belas kategori operator — jauh lebih banyak dari yang biasanya diajarkan di tutorial dasar. Yang membuat PHP berbeda dari banyak bahasa lain adalah perilaku beberapa operatornya yang tidak intuitif: operator == melakukan konversi tipe secara diam-diam, operator and dan && punya precedence berbeda meski keduanya berarti “dan”, dan operator + pada array berperilaku sangat berbeda dari yang mungkin kamu harapkan. Artikel ini membahas semua operator PHP secara mendalam — bukan sekadar daftarnya, tapi juga jebakan yang sering menyebabkan bug dan cara menggunakannya dengan benar.

Operator Aritmatika #

Operator aritmatika melakukan operasi matematika dasar. Semuanya bekerja pada nilai numerik (integer dan float), dengan beberapa perilaku edge case yang penting diketahui.

<?php
$a = 17;
$b = 5;

echo $a + $b;   // 22  — penjumlahan
echo $a - $b;   // 12  — pengurangan
echo $a * $b;   // 85  — perkalian
echo $a / $b;   // 3.4 — pembagian (menghasilkan float jika tidak habis)
echo $a % $b;   // 2   — modulo (sisa bagi)
echo $a ** $b;  // 1419857 — pangkat (PHP 5.6+)

Perilaku Pembagian #

Operator / selalu menghasilkan tipe yang tepat — integer jika habis dibagi, float jika tidak:

<?php
var_dump(10 / 2);   // int(5)    — habis dibagi, hasil integer
var_dump(10 / 3);   // float(3.333...) — tidak habis, hasil float
var_dump(10 / 3.0); // float(3.333...) — salah satu float, hasil float

// Jika kamu butuh pembagian integer (buang sisa):
echo intdiv(10, 3); // 3 — fungsi khusus pembagian integer (PHP 7+)
echo (int)(10 / 3); // 3 — casting ke int (truncate, bukan round)
echo floor(10 / 3); // 3 — floor division

Modulo dan Nilai Negatif #

<?php
// Tanda hasil modulo mengikuti tanda pembilang (bukan pembagi)
echo  10 %  3;  //  1
echo -10 %  3;  // -1 — negatif karena pembilang negatif
echo  10 % -3;  //  1 — positif karena pembilang positif
echo -10 % -3;  // -1

// Penggunaan umum modulo: cek kelipatan
$angka = 15;
echo ($angka % 3 === 0) ? "kelipatan 3" : "bukan kelipatan 3"; // kelipatan 3
echo ($angka % 2 === 0) ? "genap" : "ganjil";                  // ganjil

// Rotasi indeks array — modulo mencegah out of bounds
$warna  = ["merah", "hijau", "biru"];
$jumlah = count($warna);
for ($i = 0; $i < 9; $i++) {
    echo $warna[$i % $jumlah] . " "; // merah hijau biru merah hijau biru...
}

Operator Pangkat #

<?php
echo 2 ** 8;    // 256 — 2 pangkat 8
echo 2 ** 0.5;  // 1.4142... — akar kuadrat (2^0.5 = √2)
echo (-2) ** 3; // -8

// Associativity pangkat adalah RIGHT-TO-LEFT
echo 2 ** 3 ** 2; // 512 — dihitung sebagai 2 ** (3 ** 2) = 2 ** 9 = 512
                  // BUKAN (2 ** 3) ** 2 = 8 ** 2 = 64!

Operator Penugasan #

Operator penugasan menyimpan nilai ke variabel. Selain = dasar, PHP menyediakan operator penugasan gabungan untuk mempersingkat ekspresi umum.

<?php
// Penugasan dasar
$x = 10;

// Operator penugasan gabungan — semua setara dengan $x = $x OP nilai
$x += 5;   // $x = $x + 5  → 15
$x -= 3;   // $x = $x - 3  → 12
$x *= 2;   // $x = $x * 2  → 24
$x /= 4;   // $x = $x / 4  → 6
$x %= 4;   // $x = $x % 4  → 2
$x **= 3;  // $x = $x ** 3 → 8

// Penugasan string
$teks  = "Halo";
$teks .= " Dunia"; // $teks = $teks . " Dunia" → "Halo Dunia"

// Penugasan null coalescing (PHP 7.4+)
$config = [];
$config['timeout'] ??= 30;  // assign 30 hanya jika null/tidak ada
$config['timeout'] ??= 60;  // tidak berubah — sudah ada nilainya (30)
echo $config['timeout'];     // 30

Penugasan Berantai #

PHP mendukung penugasan berantai — nilai di-assign dari kanan ke kiri:

<?php
// Berantai ke kiri — semua variabel mendapat nilai yang sama
$a = $b = $c = 0;
echo "$a $b $c"; // 0 0 0

// Hati-hati: ini bukan perbandingan!
// ANTI-PATTERN: typo yang sangat umum
$aktif = false;
if ($aktif = true) {    // ✗ ini PENUGASAN, bukan perbandingan!
    echo "selalu masuk sini karena $aktif = true selalu bernilai true";
}

// BENAR: gunakan == atau ===
if ($aktif === true) {  // ✓ perbandingan
    echo "aktif";
}

Operator Perbandingan #

Operator perbandingan mengembalikan true atau false. Ini adalah bagian yang paling kritis untuk dipahami dengan benar di PHP, karena perbedaan antara == dan === bisa menyebabkan bug yang sangat sulit ditemukan.

Tabel Lengkap Operator Perbandingan #

OperatorNamaContohHasilKeterangan
==Sama (longgar)1 == "1"trueKonversi tipe otomatis
===Identik (ketat)1 === "1"falseTipe harus sama
!=Tidak sama (longgar)1 != "2"trueKonversi tipe otomatis
<>Tidak sama (longgar)1 <> "2"trueAlias dari !=
!==Tidak identik (ketat)1 !== "1"trueTipe harus berbeda
<Kurang dari1 < 2true
>Lebih dari2 > 1true
<=Kurang dari atau sama1 <= 1true
>=Lebih dari atau sama2 >= 1true
<=>Spaceship1 <=> 2-1Mengembalikan -1, 0, atau 1

Perbandingan Longgar == — Jebakan Type Juggling #

Operator == melakukan konversi tipe sebelum membandingkan. Hasilnya bisa sangat mengejutkan:

<?php
// Jebakan == yang paling umum
var_dump(0    == "foo");   // PHP 7: true  | PHP 8: false (perubahan besar!)
var_dump(0    == "");      // PHP 7: true  | PHP 8: false
var_dump(0    == "0");     // true  (kedua versi)
var_dump(0    == false);   // true
var_dump(0    == null);    // true
var_dump(""   == false);   // true
var_dump(""   == null);    // true
var_dump("1"  == "01");    // true  — keduanya dikonversi ke int 1
var_dump("10" == "1e1");   // true  — notasi ilmiah!
var_dump(100  == "1e2");   // true
var_dump(null == false);   // true
var_dump(null == 0);       // true
var_dump(null == "");      // true
var_dump(null == "0");     // false — ini beda!

// Kasus yang sangat berbahaya:
$password_hash = "0e123456789"; // hash MD5 tertentu dimulai "0e..."
$input_hash    = "0e987654321"; // hash MD5 berbeda yang juga "0e..."
var_dump($password_hash == $input_hash); // true! — "magic hash" attack!
// PHP mengonversi keduanya ke float 0 * 10^xxx = 0
// SELALU gunakan === untuk membandingkan hash
Jangan gunakan == untuk membandingkan hash kriptografi, token, atau password. String yang dimulai dengan 0e diinterpretasikan PHP sebagai notasi ilmiah (0 * 10^n = 0), sehingga dua hash yang berbeda bisa dianggap sama. Gunakan === atau fungsi hash_equals() yang dirancang khusus tahan terhadap timing attack.

Perbandingan Ketat === #

Operator === membandingkan nilai dan tipe tanpa konversi apapun:

<?php
var_dump(1   === 1);      // true  — sama nilai, sama tipe
var_dump(1   === "1");    // false — nilai sama, tipe berbeda (int vs string)
var_dump(1   === 1.0);    // false — int vs float
var_dump(null === false); // false — null vs bool
var_dump([]  === []);     // true  — array kosong identik
var_dump([1] === [1]);    // true
var_dump([1] === ["1"]);  // false — elemen berbeda tipe

// Untuk object: === cek apakah INSTANCE yang sama (bukan hanya sama nilai)
$a = new stdClass();
$b = new stdClass();
$c = $a;

var_dump($a === $b); // false — dua instance berbeda meski propertinya sama
var_dump($a === $c); // true  — variabel yang sama merujuk instance yang sama
var_dump($a == $b);  // true  — == pada object cek apakah tipe dan properti sama

Operator Spaceship <=> #

Spaceship mengembalikan -1 (kurang), 0 (sama), atau 1 (lebih) — sangat berguna sebagai callback sorting:

<?php
// Nilai yang dikembalikan
echo 1 <=> 2;   // -1 (kiri lebih kecil)
echo 2 <=> 2;   //  0 (sama)
echo 3 <=> 2;   //  1 (kiri lebih besar)

// Penggunaan paling umum: callback usort()
$produk = [
    ["nama" => "Laptop",  "harga" => 15000000],
    ["nama" => "Mouse",   "harga" => 250000],
    ["nama" => "Monitor", "harga" => 5000000],
];

// Sort ascending berdasarkan harga
usort($produk, fn($a, $b) => $a["harga"] <=> $b["harga"]);

// Sort descending (balik operan)
usort($produk, fn($a, $b) => $b["harga"] <=> $a["harga"]);

// Multi-kriteria: sort by harga ascending, lalu nama ascending jika harga sama
usort($produk, function($a, $b) {
    $hargaCmp = $a["harga"] <=> $b["harga"];
    if ($hargaCmp !== 0) return $hargaCmp;
    return $a["nama"] <=> $b["nama"];
});

// Lebih ringkas dengan arrow function
usort($produk, fn($a, $b)
    => [$a["harga"], $a["nama"]] <=> [$b["harga"], $b["nama"]]
);
// PHP membandingkan array element-by-element — teknik sorting tuple yang elegan

Operator Logika #

Operator logika digunakan untuk menggabungkan atau membalik kondisi boolean. PHP memiliki dua set operator logika yang terlihat sama tapi punya precedence berbeda — inilah sumber bug yang cukup umum.

<?php
$a = true;
$b = false;

// Operator simbol (precedence tinggi)
var_dump($a && $b);  // false — AND
var_dump($a || $b);  // true  — OR
var_dump(!$a);       // false — NOT
var_dump($a xor $b); // true  — XOR (true jika tepat satu yang true)

// Operator kata (precedence rendah — di bawah = )
var_dump($a and $b); // false
var_dump($a or $b);  // true
var_dump($a xor $b); // true

Jebakan Precedence: and/or vs &&/|| #

Ini adalah salah satu jebakan precedence paling umum di PHP:

<?php
// ANTI-PATTERN: mengira 'and' dan '&&' identik
$hasil = true and false;
var_dump($hasil); // bool(true) — MENGEJUTKAN!

// Ini terjadi karena precedence '=' lebih tinggi dari 'and':
// PHP membaca sebagai: ($hasil = true) and false
// Jadi $hasil = true, lalu ekspresi 'and false' dievaluasi tapi dibuang

$hasil = true && false;
var_dump($hasil); // bool(false) — ini yang diharapkan
// '&&' punya precedence lebih tinggi dari '=':
// PHP membaca sebagai: $hasil = (true && false)

// BENAR: gunakan && dan || selalu, hindari and/or kecuali memang perlu
$aktif  = true;
$terverifikasi = false;

if ($aktif && $terverifikasi) {
    echo "akses diberikan";
}

Short-Circuit Evaluation #

PHP menggunakan short-circuit evaluation — ekspresi dihentikan segera setelah hasilnya pasti:

<?php
function cekA(): bool
{
    echo "cekA dipanggil\n";
    return false;
}

function cekB(): bool
{
    echo "cekB dipanggil\n";
    return true;
}

// && berhenti di cekA() karena false && apapun = false
if (cekA() && cekB()) { }
// Output: "cekA dipanggil" — cekB tidak pernah dipanggil!

// || berhenti di kondisi pertama yang true
$user = null;
$nama = $user?->getNama() || "Tamu";
// Jika user null, ekspresi setelah || tidak pernah dievaluasi

// Pola idiomatik: gunakan short-circuit untuk guard
function prosesFile(string $path): void
{
    file_exists($path) || throw new \InvalidArgumentException("File tidak ada: $path");
    is_readable($path) || throw new \RuntimeException("File tidak bisa dibaca: $path");

    // lanjut proses...
}

Operator Increment dan Decrement #

Operator increment (++) dan decrement (--) menambah atau mengurangi nilai sebesar 1. Posisi operator (sebelum atau sesudah variabel) menentukan kapan perubahan terjadi relatif terhadap evaluasi ekspresi.

<?php
$x = 5;

// Pre-increment: tambah dulu, lalu kembalikan nilai baru
echo ++$x; // 6 — $x sekarang 6

// Post-increment: kembalikan nilai lama dulu, lalu tambah
echo $x++; // 6 — nilai lama dikembalikan, $x sekarang 7
echo $x;   // 7

// Pre-decrement
echo --$x; // 6
// Post-decrement
echo $x--; // 6 — nilai lama, $x sekarang 5
echo $x;   // 5

Perilaku pada String dan Null #

PHP memiliki perilaku menarik saat increment/decrement diterapkan pada string dan null — ini mewarisi konvensi dari Perl:

<?php
// Increment string — "naik" ke karakter berikutnya
$s = "a";
$s++;
echo $s; // "b"

$s = "z";
$s++;
echo $s; // "aa"

$s = "A9";
$s++;
echo $s; // "B0"

$s = "Az";
$s++;
echo $s; // "Ba"

// NULL increment menghasilkan 1
$n = null;
$n++;
echo $n; // 1

// PERHATIAN: decrement pada string dan null tidak berperilaku simetris!
$s = "b";
$s--;
echo $s; // "b" — tidak berubah! decrement tidak berlaku untuk string

$n = null;
$n--;
echo $n; // -1 — decrement null menghasilkan -1? Tidak! ini error di PHP 8+
// Di PHP 8.3+, decrement null menghasilkan -1 (perilaku berubah dari versi lama)

Operator String #

PHP hanya memiliki dua operator khusus untuk string:

<?php
// Operator concatenation (.) — menggabungkan dua string
$depan  = "Halo";
$tengah = ", ";
$akhir  = "Dunia!";

$kalimat = $depan . $tengah . $akhir;
echo $kalimat; // "Halo, Dunia!"

// Non-string akan dikonversi ke string otomatis
echo "Nilai: " . 42;        // "Nilai: 42"
echo "Pi: " . 3.14;         // "Pi: 3.14"
echo "Aktif: " . true;      // "Aktif: 1"
echo "Nonaktif: " . false;  // "Nonaktif: " (false jadi string kosong)

// Operator penugasan concatenation (.=)
$log = "[2024-01-01] ";
$log .= "Server started. ";
$log .= "Port 8080.";
echo $log; // "[2024-01-01] Server started. Port 8080."

// Untuk membangun string panjang dalam loop, .= lebih efisien dari re-assign
$html = "";
foreach ($items as $item) {
    $html .= "<li>{$item['nama']}</li>\n";
}

Concatenation vs Interpolasi #

<?php
$nama  = "Budi";
$kota  = "Jakarta";

// ANTI-PATTERN: concatenation berulang untuk banyak variabel — verbose
$pesan = "Halo " . $nama . ", kamu dari " . $kota . "!";

// BENAR: interpolasi string lebih bersih
$pesan = "Halo {$nama}, kamu dari {$kota}!";

// Untuk operasi yang lebih kompleks (fungsi, ekspresi), tetap pakai concatenation
$pesan = "Total: Rp " . number_format($total, 0, ',', '.') . " (sudah termasuk PPN)";

// Atau sprintf untuk format yang lebih terstruktur
$pesan = sprintf("Total: Rp %s (sudah termasuk PPN)", number_format($total, 0, ',', '.'));

Operator Bitwise #

Operator bitwise bekerja langsung pada representasi biner dari integer. Meski jarang dipakai di web biasa, mereka sangat berguna untuk flag permission, enkripsi sederhana, dan manipulasi bit.

<?php
// Representasi biner: 5 = 0101, 3 = 0011

echo 5 & 3;   // 1  (0101 AND 0011 = 0001) — keduanya 1
echo 5 | 3;   // 7  (0101 OR  0011 = 0111) — salah satu 1
echo 5 ^ 3;   // 6  (0101 XOR 0011 = 0110) — tepat satu 1
echo ~5;       // -6 (NOT 0101 = ...11111010 dalam two's complement)
echo 5 << 1;  // 10 (geser kiri 1 bit: 0101 → 1010)
echo 5 >> 1;  // 2  (geser kanan 1 bit: 0101 → 0010)

Pola Flag dengan Bitwise #

Penggunaan paling umum bitwise di PHP adalah sistem permission / flag:

<?php
// Definisikan flag sebagai konstanta power-of-2
const PERM_BACA   = 0b001; // 1
const PERM_TULIS  = 0b010; // 2
const PERM_HAPUS  = 0b100; // 4

// Gabungkan beberapa permission dengan OR
$permisiAdmin = PERM_BACA | PERM_TULIS | PERM_HAPUS; // 7 (0b111)
$permisiUser  = PERM_BACA;                             // 1 (0b001)
$permisiEditor = PERM_BACA | PERM_TULIS;              // 3 (0b011)

// Cek apakah permission tertentu aktif dengan AND
function punyaPermisi(int $permisi, int $flag): bool
{
    return ($permisi & $flag) === $flag;
}

var_dump(punyaPermisi($permisiAdmin, PERM_HAPUS));  // true
var_dump(punyaPermisi($permisiUser, PERM_HAPUS));   // false
var_dump(punyaPermisi($permisiEditor, PERM_TULIS)); // true

// Tambah permission dengan OR
$permisiUser |= PERM_TULIS;
var_dump(punyaPermisi($permisiUser, PERM_TULIS)); // true — sudah ditambahkan

// Hapus permission dengan AND NOT
$permisiEditor &= ~PERM_TULIS;
var_dump(punyaPermisi($permisiEditor, PERM_TULIS)); // false — sudah dihapus

Pola ini juga dipakai secara luas di fungsi bawaan PHP — misalnya json_encode(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), di mana JSON_PRETTY_PRINT dan JSON_UNESCAPED_UNICODE adalah konstanta bitwise flag.


Operator Array #

PHP memiliki operator khusus untuk bekerja dengan array. Perilakunya berbeda dari operator perbandingan biasa dan perlu dipahami dengan seksama.

<?php
$a = ["x" => 1, "y" => 2];
$b = ["y" => 9, "z" => 3];

// Union (+): gabungkan array, key dari kiri yang menang jika ada duplikat
$union = $a + $b;
print_r($union);
// Array ( [x] => 1 [y] => 2 [z] => 3 )
// Perhatikan: [y] tetap 2 (dari $a), bukan 9 (dari $b)!

// ANTI-PATTERN: gunakan + saat ingin merge dengan override
// BENAR: gunakan array_merge() jika key kanan harus menang
$merge = array_merge($a, $b);
print_r($merge);
// Array ( [x] => 1 [y] => 9 [z] => 3 )
// [y] jadi 9 (dari $b yang override $a)

Perbandingan Array #

<?php
$a = ["a" => 1, "b" => 2];
$b = ["b" => 2, "a" => 1]; // urutan berbeda
$c = ["a" => 1, "b" => "2"]; // tipe nilai berbeda

// == : sama jika key-value sama, urutan tidak penting, konversi tipe
var_dump($a == $b);  // true  — key-value sama meski urutan beda
var_dump($a == $c);  // true  — "2" == 2 setelah konversi

// === : sama jika key-value sama, urutan HARUS sama, tipe harus sama
var_dump($a === $b); // false — urutan berbeda!
var_dump($a === $c); // false — tipe berbeda (int vs string)

$d = ["a" => 1, "b" => 2]; // identik dengan $a
var_dump($a === $d); // true

Operator Ternary dan Variannya #

Ternary dan variannya menyediakan cara ringkas menulis ekspresi kondisional sebagai ekspresi (bukan statement), sehingga hasilnya bisa langsung di-assign atau digunakan dalam ekspresi yang lebih besar.

<?php
$umur = 20;

// Ternary penuh: kondisi ? nilai_true : nilai_false
$status = $umur >= 18 ? "dewasa" : "anak-anak";

// Elvis operator (?:) — shorthand ternary tanpa ekspresi tengah
// Mengembalikan operan kiri jika truthy, operan kanan jika falsy
$nama  = "";
$tampil = $nama ?: "Tamu"; // "Tamu" — karena $nama falsy (string kosong)

$nama2  = "Budi";
$tampil2 = $nama2 ?: "Tamu"; // "Budi" — karena $nama2 truthy

// Setara dengan: $tampil = $nama ? $nama : "Tamu";
// tapi lebih ringkas karena tidak perlu tulis $nama dua kali

// Null coalescing (??) — hanya cek null/undefined, bukan falsy
$config = ["host" => "localhost", "port" => null];

echo $config["host"] ?? "127.0.0.1"; // "localhost" — ada dan bukan null
echo $config["port"] ?? 3306;         // 3306 — nilainya null, pakai default
echo $config["user"] ?? "root";       // "root" — key tidak ada

// Perbedaan ?: vs ??
$nilai = 0;
echo $nilai ?: "default";  // "default" — 0 adalah falsy!
echo $nilai ?? "default";  // 0 — 0 bukan null, jadi kembalikan $nilai

Null Coalescing Assignment ??= #

<?php
// Assign nilai hanya jika variabel null atau tidak terdefinisi
$opsi = [];
$opsi['debug']   ??= false;  // set ke false karena belum ada
$opsi['timeout'] ??= 30;     // set ke 30
$opsi['timeout'] ??= 60;     // TIDAK berubah — sudah ada nilainya (30)

// Berguna saat membangun array konfigurasi secara inkremental
function defaultConfig(array &$config): void
{
    $config['debug']    ??= false;
    $config['timeout']  ??= 30;
    $config['max_retry'] ??= 3;
    $config['cache_ttl'] ??= 3600;
}

$userConfig = ['debug' => true, 'timeout' => 10];
defaultConfig($userConfig);

// debug dan timeout tidak berubah (sudah ada), tapi max_retry dan cache_ttl ditambahkan
print_r($userConfig);

Ternary Bersarang — Kapan Berhenti #

<?php
// ANTI-PATTERN: ternary bersarang yang susah dibaca
$level = 3;
$label = $level === 1 ? "Junior"
       : $level === 2 ? "Mid"
       : $level === 3 ? "Senior"
       : "Unknown";

// BENAR: gunakan match untuk kasus seperti ini — jauh lebih jelas
$label = match($level) {
    1 => "Junior",
    2 => "Mid",
    3 => "Senior",
    default => "Unknown",
};

// Atau array lookup untuk mapping sederhana
$labels = [1 => "Junior", 2 => "Mid", 3 => "Senior"];
$label  = $labels[$level] ?? "Unknown";

Precedence dan Associativity #

Precedence menentukan operator mana yang dievaluasi lebih dulu saat ada beberapa operator dalam satu ekspresi. Associativity menentukan arah evaluasi saat operator punya precedence yang sama.

Tabel precedence PHP (dari tertinggi ke terendah, beberapa kelompok terpenting):

PrecedenceOperatorAssociativity
Tertinggiclone, new
**Kanan ke kiri
++, --, ~, (int), (string), dll.
instanceof
!
*, /, %Kiri ke kanan
+, -, .Kiri ke kanan
<<, >>Kiri ke kanan
<, <=, >, >=
==, !=, ===, !==, <=>
&Kiri ke kanan
^Kiri ke kanan
|Kiri ke kanan
&&Kiri ke kanan
||Kiri ke kanan
??Kanan ke kiri
? :
=, +=, -=, dll.Kanan ke kiri
yield
andKiri ke kanan
xorKiri ke kanan
TerendahorKiri ke kanan
<?php
// Contoh yang sering membingungkan:

// 1. Konkatenasi dan penjumlahan — precedence sama, kiri ke kanan
echo "Total: " . 2 + 3;  // PHP error atau "3" — SALAH!
// Dievaluasi: ("Total: " . 2) + 3 → "Total: 2" + 3
// PHP konversi string ke int → 0 + 3 = 3

echo "Total: " . (2 + 3); // "Total: 5" — BENAR dengan tanda kurung

// 2. && vs and
$a = true;
$b = false;
$c = $a && $b;   // $c = false (&&  lebih tinggi dari =)
$d = $a and $b;  // $d = true  (=   lebih tinggi dari and!)

// 3. ?? vs ?:
$x = null;
echo $x ?? "null-default" ?: "falsy-default";
// Dievaluasi: ($x ?? "null-default") ?: "falsy-default"
// → "null-default" ?: "falsy-default"
// → "null-default" (truthy, dikembalikan)

// Ketika tidak yakin, gunakan tanda kurung
echo ($x ?? "null-default");
Selalu gunakan tanda kurung () ketika menggabungkan operator yang berbeda kategori. Precedence PHP tidak selalu intuitif — terutama di sekitar . (concatenation), ??, ?:, dan perbedaan && vs and. Tanda kurung membuat maksud kamu eksplisit dan mencegah bug precedence yang halus.

Ringkasan #

  • Selalu gunakan === bukan == untuk perbandingan — == melakukan konversi tipe implisit yang hasilnya sering tidak terduga, dan perilakunya berubah antara PHP 7 dan PHP 8.
  • && dan and bukan sinonimand punya precedence lebih rendah dari =, sehingga $x = true and false menghasilkan $x = true, bukan false. Gunakan && dan || secara konsisten.
  • Spaceship <=> adalah cara paling bersih untuk callback usort() — mendukung multi-kriteria dengan membandingkan array secara langsung.
  • Short-circuit evaluation — pada &&, ekspresi kanan tidak dievaluasi jika kiri sudah false. Pada ||, kanan tidak dievaluasi jika kiri sudah true. Manfaatkan ini untuk guard condition yang efisien.
  • ?? vs ?:?? hanya cek null/undefined; ?: cek falsy (termasuk 0, “”, false). Gunakan ?? untuk nilai default yang menggantikan null, ?: untuk fallback dari nilai falsy.
  • Operator + pada array tidak sama dengan array_merge()+ mempertahankan key dari kiri jika ada duplikat; array_merge() membiarkan key dari kanan menang.
  • Bitwise operator untuk flag permission — pola PERM_BACA | PERM_TULIS adalah cara idiomatik menyimpan beberapa flag boolean dalam satu integer.
  • Gunakan tanda kurung saat menggabungkan operator dari kategori berbeda — precedence PHP tidak selalu intuitif, dan tanda kurung membuat niat kamu eksplisit.

← Sebelumnya: Tipe Data   Berikutnya: Seleksi Kondisi →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact