Variabel #
Variabel adalah konsep paling mendasar di PHP, tapi juga tempat banyak keanehan bahasa ini tersembunyi. PHP adalah bahasa dynamically typed — tipe sebuah variabel ditentukan dari nilai yang kamu simpan ke dalamnya, bukan dari deklarasi eksplisit. Ini membuat kode cepat ditulis, tapi juga membuka celah untuk bug yang halus: variabel yang tiba-tiba berganti tipe di tengah program, scope yang berbeda dari yang kamu kira, atau nilai yang berubah tanpa sengaja karena referensi yang tidak diperhatikan. Artikel ini membahas semua aspek variabel PHP secara menyeluruh — dari aturan dasar penamaan, cara scope bekerja, perbedaan kritis antara copy-by-value dan pass-by-reference, hingga fitur destrukturing yang membuat kode jauh lebih ekspresif.
Dasar Variabel PHP #
Setiap variabel PHP diawali dengan tanda dolar $ diikuti nama variabel. PHP tidak memiliki kata kunci deklarasi seperti var, let, atau const untuk variabel biasa — kamu langsung menulis nama dan mengassign nilainya.
<?php
$nama = "Budi Santoso"; // string
$umur = 28; // integer
$tinggi = 172.5; // float
$aktif = true; // boolean
$alamat = null; // null — belum ada nilai
PHP langsung membuat variabel saat pertama kali di-assign. Tidak ada deklarasi terpisah yang diperlukan, dan tipe variabel berubah otomatis mengikuti nilai yang diberikan:
<?php
$data = 42; // integer
$data = "teks"; // sekarang string — valid di PHP
$data = [1, 2, 3]; // sekarang array — tetap valid
$data = null; // sekarang null
Fleksibilitas ini berguna, tapi bisa menjadi sumber bug. Di proyek nyata, satu variabel sebaiknya hanya menyimpan satu jenis data sepanjang hidupnya.
Aturan Penamaan Variabel #
Nama variabel PHP mengikuti aturan berikut:
<?php
// ✓ Nama yang valid
$nama = "Budi";
$namaLengkap = "Budi Santoso"; // camelCase — konvensi umum PHP
$nama_lengkap = "Budi Santoso"; // snake_case — juga umum
$_internal = "nilai"; // boleh diawali underscore
$nilai2024 = 100; // boleh mengandung angka (tapi tidak di awal)
$HTMLParser = "parser"; // boleh huruf kapital di manapun
// ✗ Nama yang tidak valid — akan menyebabkan parse error
// $2024nilai = 100; // tidak boleh diawali angka
// $nama-ku = "x"; // tanda hubung bukan karakter valid
// $nilai akhir = 0; // spasi tidak diperbolehkan
// $kelas@id = 1; // karakter spesial tidak diperbolehkan
Satu aturan penting yang sering mengejutkan pemula: nama variabel PHP bersifat case-sensitive. $nama, $Nama, dan $NAMA adalah tiga variabel yang berbeda dan independen.
<?php
$kota = "Jakarta";
$Kota = "Bandung";
$KOTA = "Surabaya";
echo $kota; // Jakarta
echo $Kota; // Bandung
echo $KOTA; // Surabaya — tiga variabel berbeda!
Konvensi Penamaan #
PHP tidak memaksa satu konvensi, tapi komunitas dan standar PSR-12 memberikan panduan yang jelas:
| Konteks | Konvensi | Contoh |
|---|---|---|
| Variabel lokal | camelCase | $namaLengkap, $totalHarga |
| Parameter fungsi | camelCase | $userId, $isActive |
| Property kelas | camelCase | $this->firstName |
| Variabel global (dihindari) | snake_case atau UPPER_SNAKE | $_config, $MAX_RETRY |
| Loop variable pendek | Huruf tunggal | $i, $j, $k (hanya untuk loop) |
Scope Variabel #
Scope menentukan di mana variabel bisa diakses. PHP memiliki tiga level scope, dan cara kerjanya berbeda dari banyak bahasa lain — terutama bagaimana fungsi mengisolasi scope-nya sendiri.
flowchart TD
A[Scope Global\nVariabel di luar fungsi/kelas] --> B{Akses dari dalam fungsi?}
B -- "Langsung\n❌ Tidak bisa" --> C[Undefined variable]
B -- "Pakai global keyword\n⚠️ Hindari jika bisa" --> D[Bisa diakses]
B -- "Pakai parameter\n✓ Cara yang benar" --> E[Bisa diakses via argumen]
F[Scope Fungsi\nVariabel lokal fungsi] --> G{Akses dari luar fungsi?}
G -- "Tidak bisa" --> H[Undefined variable]
G -- "Lewat return value\n✓ Cara yang benar" --> I[Bisa diakses]Scope Global dan Scope Fungsi #
Berbeda dari JavaScript atau Python, variabel global PHP tidak otomatis tersedia di dalam fungsi:
<?php
$aplikasi = "PHP Tutorial";
$versi = "8.3";
function tampilkanInfo(): void
{
// ANTI-PATTERN: asumsi variabel global tersedia di dalam fungsi
echo $aplikasi; // PHP Warning: Undefined variable $aplikasi
echo $versi; // PHP Warning: Undefined variable $versi
}
// BENAR: kirim lewat parameter
function tampilkanInfoV2(string $aplikasi, string $versi): void
{
echo "$aplikasi versi $versi";
}
tampilkanInfoV2($aplikasi, $versi); // PHP Tutorial versi 8.3
Isolasi ini adalah fitur, bukan bug — ini mencegah fungsi secara tidak sengaja bergantung pada atau memodifikasi state global, yang membuat kode lebih mudah di-test dan di-debug.
Keyword global
#
PHP menyediakan keyword global untuk mengakses variabel global dari dalam fungsi, tapi ini hampir selalu merupakan code smell:
<?php
$koneksiDb = null; // variabel global
// ANTI-PATTERN: akses global dari dalam fungsi
function ambilUser(int $id): array
{
global $koneksiDb; // mengambil referensi ke variabel global
// fungsi ini sekarang punya hidden dependency ke $koneksiDb global
// tidak mungkin di-test tanpa menyiapkan variabel global terlebih dahulu
$stmt = $koneksiDb->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch();
}
// BENAR: dependency injection — kirim koneksi sebagai parameter
function ambilUserV2(PDO $db, int $id): array
{
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch() ?: [];
}
Variabel Statis #
Variabel statis di dalam fungsi tetap mempertahankan nilainya antara pemanggilan. Berbeda dari variabel lokal biasa yang di-reset setiap kali fungsi dipanggil:
<?php
function hitungPanggilan(): int
{
static $jumlah = 0; // diinisialisasi SEKALI, lalu nilai dipertahankan
$jumlah++;
return $jumlah;
}
echo hitungPanggilan(); // 1
echo hitungPanggilan(); // 2
echo hitungPanggilan(); // 3
// Berguna untuk memoization sederhana
function fibonacci(int $n): int
{
static $cache = [];
if ($n <= 1) return $n;
if (isset($cache[$n])) return $cache[$n];
$cache[$n] = fibonacci($n - 1) + fibonacci($n - 2);
return $cache[$n];
}
echo fibonacci(10); // 55
echo fibonacci(10); // 55 — dari cache, tidak hitung ulang
Pass-by-Value vs Pass-by-Reference #
Ini adalah salah satu konsep yang paling penting — dan paling sering disalahpahami — tentang variabel PHP.
Pass-by-Value (Default) #
Secara default, PHP meneruskan salinan nilai ke fungsi. Memodifikasi parameter di dalam fungsi tidak mempengaruhi variabel aslinya:
<?php
function tambahSatu(int $angka): int
{
$angka++; // modifikasi salinan, bukan nilai asli
return $angka;
}
$nilai = 10;
$hasil = tambahSatu($nilai);
echo $nilai; // 10 — tidak berubah
echo $hasil; // 11
// Sama berlaku untuk assignment biasa
$a = [1, 2, 3];
$b = $a; // $b adalah SALINAN dari $a
$b[] = 4; // menambah elemen ke salinan
var_dump(count($a)); // int(3) — $a tidak terpengaruh
var_dump(count($b)); // int(4)
Pass-by-Reference #
Dengan menambahkan &, kamu meneruskan referensi ke variabel asli — bukan salinan. Perubahan di dalam fungsi langsung mempengaruhi variabel asli:
<?php
function gandakanNilai(int &$angka): void
{
$angka *= 2; // memodifikasi variabel asli langsung
}
$nilai = 15;
gandakanNilai($nilai); // tidak perlu return — modifikasi langsung
echo $nilai; // 30 — nilai asli berubah!
// Contoh praktis: fungsi sort bawaan PHP memodifikasi array via referensi
$buah = ["mangga", "apel", "jeruk"];
sort($buah); // sort() menerima array by reference, mengubah array asli
print_r($buah); // ["apel", "jeruk", "mangga"]
Kapan Pakai Reference vs Return Value #
Gunakan return value untuk hampir semua kasus. Referensi hanya tepat dalam situasi spesifik:
<?php
// ANTI-PATTERN: pakai reference padahal return value lebih jelas
function hitungDiskon(float &$harga, float $persen): void
{
$harga = $harga * (1 - $persen);
}
$harga = 100000.0;
hitungDiskon($harga, 0.1);
// pembaca harus tahu bahwa $harga berubah — tidak intuitif dari sisi pemanggil
// BENAR: return value eksplisit dan lebih mudah dipahami
function hitungDiskonV2(float $harga, float $persen): float
{
return $harga * (1 - $persen);
}
$harga = 100000.0;
$hargaDiskon = hitungDiskonV2($harga, 0.1);
// jelas: $harga asli tidak berubah, hasil ada di $hargaDiskon
// ✓ Reference tepat digunakan untuk: swap dua variabel
function swap(mixed &$a, mixed &$b): void
{
$temp = $a;
$a = $b;
$b = $temp;
}
$x = "pertama";
$y = "kedua";
swap($x, $y);
echo $x; // kedua
echo $y; // pertama
Reference ke Elemen Array #
Reference juga bisa dipakai saat iterasi array dengan foreach ketika kamu perlu memodifikasi elemen:
<?php
$harga = [10000, 25000, 50000, 100000];
// ANTI-PATTERN: modifikasi array via index — verbose
foreach ($harga as $i => $nilai) {
$harga[$i] = $nilai * 1.11; // tambah PPN
}
// BENAR: foreach dengan reference — lebih bersih
foreach ($harga as &$nilai) {
$nilai *= 1.11;
}
unset($nilai); // WAJIB! putus referensi setelah loop selesai
// Kenapa unset() wajib? Karena $nilai masih bereferensi ke elemen terakhir.
// Jika ada kode berikutnya yang assign ke $nilai, elemen terakhir array ikut berubah!
Selalu panggilunset($variabelRef)setelahforeachyang menggunakan referensi (&). Tanpanya,$variabelRefmasih menunjuk ke elemen terakhir array, dan setiap assignment ke variabel dengan nama yang sama di kode selanjutnya akan memodifikasi elemen tersebut — ini adalah sumber bug yang sangat halus dan sulit ditemukan.
Memeriksa dan Menghapus Variabel #
PHP menyediakan beberapa fungsi untuk memeriksa keberadaan dan tipe variabel.
isset(), empty(), dan is_null() #
Ketiga fungsi ini terlihat serupa tapi punya perilaku berbeda yang penting dipahami:
<?php
$a = 0;
$b = "";
$c = null;
$d = false;
$e = [];
// $f tidak didefinisikan sama sekali
// isset() — true jika variabel ADA dan BUKAN null
var_dump(isset($a)); // true — ada, nilainya 0
var_dump(isset($b)); // true — ada, nilainya ""
var_dump(isset($c)); // false — ada tapi nilainya null
var_dump(isset($f)); // false — tidak ada
// empty() — true jika variabel "kosong" (falsy atau tidak ada)
var_dump(empty($a)); // true — 0 dianggap kosong
var_dump(empty($b)); // true — "" dianggap kosong
var_dump(empty($c)); // true — null dianggap kosong
var_dump(empty($d)); // true — false dianggap kosong
var_dump(empty($e)); // true — [] dianggap kosong
var_dump(empty($f)); // true — tidak ada dianggap kosong
// is_null() — true hanya jika nilainya null (variabel harus ada)
var_dump(is_null($a)); // false
var_dump(is_null($c)); // true
// is_null($f) — akan menghasilkan warning jika $f tidak didefinisikan
Tabel ringkas untuk membantu memilih:
| Fungsi | Undefined | null | 0 | "" | false | [] |
|---|---|---|---|---|---|---|
isset() | false | false | true | true | true | true |
empty() | true | true | true | true | true | true |
is_null() | warning | true | false | false | false | false |
Menghapus Variabel dengan unset() #
unset() menghapus variabel dari memory. Variabel yang di-unset tidak ada lagi di scope tersebut:
<?php
$data = ["budi", "siti", "dani"];
unset($data[1]); // hapus elemen indeks 1
print_r($data);
// Array ( [0] => budi [2] => dani )
// Perhatikan: indeks tidak di-reindex otomatis!
// Untuk reindex setelah unset, gunakan array_values()
$data = array_values($data);
print_r($data);
// Array ( [0] => budi [1] => dani )
// Hapus variabel scalar
$sementara = "data sementara";
unset($sementara);
var_dump(isset($sementara)); // bool(false)
Tipe Variabel dan Konversi #
PHP secara otomatis mengkonversi tipe variabel sesuai konteks penggunaan. Memahami aturan konversi ini penting untuk menghindari bug.
Mengecek Tipe Variabel #
<?php
$nilai = 42;
// gettype() — kembalikan nama tipe sebagai string
echo gettype($nilai); // "integer"
// is_*() — kembalikan boolean
var_dump(is_int($nilai)); // true
var_dump(is_float($nilai)); // false
var_dump(is_string($nilai)); // false
var_dump(is_bool($nilai)); // false
var_dump(is_array($nilai)); // false
var_dump(is_null($nilai)); // false
var_dump(is_numeric($nilai));// true — termasuk string numerik seperti "42"
// var_dump() — tampilkan tipe dan nilai sekaligus (paling berguna untuk debug)
var_dump($nilai); // int(42)
Konversi Eksplisit (Casting) #
Daripada mengandalkan konversi implisit PHP, lebih baik melakukan casting eksplisit saat membutuhkan tipe tertentu:
<?php
$input = "42.7 persen"; // string dari user input
// Casting eksplisit
$asInt = (int) $input; // 42 — ambil bagian integer di awal string
$asFloat = (float) $input; // 42.7 — ambil bagian float di awal string
$asBool = (bool) $input; // true — string non-kosong adalah true
$asStr = (string) 3.14; // "3.14"
// intval(), floatval(), strval() — alternatif fungsi
$asInt2 = intval($input); // 42
$asInt3 = intval("0xFF", 16); // 255 — intval() bisa terima basis
// settype() — konversi di tempat (modifikasi variabel asli)
$angka = "100";
settype($angka, "integer");
var_dump($angka); // int(100)
Nilai yang Dianggap false (Falsy)
#
PHP mengkonversi nilai ke boolean saat digunakan dalam konteks kondisional. Nilai-nilai berikut dianggap false:
<?php
// Semua nilai ini dianggap false dalam konteks boolean
$falsy = [
false, // boolean false
0, // integer nol
0.0, // float nol
"", // string kosong
"0", // string "0" — ini mengejutkan banyak orang!
[], // array kosong
null, // null
];
foreach ($falsy as $nilai) {
if (!$nilai) {
echo gettype($nilai) . " '" . var_export($nilai, true) . "' adalah falsy\n";
}
}
// Semua nilai lain dianggap true, termasuk:
var_dump((bool) "false"); // true! — string non-kosong, meski isinya "false"
var_dump((bool) "0.0"); // true! — string "0.0" bukan "0", jadi true
var_dump((bool) -1); // true! — semua integer non-nol adalah true
var_dump((bool) [0]); // true! — array dengan elemen adalah true
Variabel Variabel #
PHP mendukung variable variables — sebuah variabel yang nilainya digunakan sebagai nama variabel lain. Fitur ini jarang diperlukan tapi penting dikenali agar tidak bingung saat menemukannya:
<?php
$kunci = "nama";
$$kunci = "Budi"; // membuat variabel $nama dengan nilai "Budi"
echo $nama; // Budi
echo $$kunci; // Budi — sama
// Level kedua
$a = "b";
$b = "c";
$c = "nilai akhir";
echo $$$a; // "nilai akhir" — PHP eval $a → "b", lalu $b → "c", lalu $c
<?php
// Contoh penggunaan yang kadang ditemui (tapi sebaiknya dihindari):
$fields = ["nama", "email", "telepon"];
$nama = "Budi";
$email = "[email protected]";
$telepon = "081234567890";
foreach ($fields as $field) {
// ANTI-PATTERN: variable variable untuk akses "dinamis"
echo $$field . "\n"; // Budi, [email protected], 081234567890
}
// BENAR: gunakan array asosiatif sebagai gantinya
$data = [
"nama" => "Budi",
"email" => "[email protected]",
"telepon" => "081234567890",
];
foreach ($fields as $field) {
echo $data[$field] . "\n"; // lebih jelas, lebih aman, mudah di-debug
}
Destrukturing Array ke Variabel #
PHP menyediakan cara elegan untuk mengekstrak nilai dari array ke variabel terpisah menggunakan list() atau sintaks [] (PHP 7.1+).
Destrukturing Array Terindeks #
<?php
$koordinat = [10.5, 106.8, 50]; // lat, lng, altitude
// Cara lama — verbose
$lat = $koordinat[0];
$lng = $koordinat[1];
$altitude = $koordinat[2];
// Cara modern dengan destrukturing
[$lat, $lng, $altitude] = $koordinat;
echo "$lat, $lng, $altitude"; // 10.5, 106.8, 50
// Lewati elemen yang tidak dibutuhkan dengan placeholder
[, $lng] = $koordinat; // hanya ambil longitude
echo $lng; // 106.8
// Berguna untuk swap variabel tanpa variabel temp
$a = "pertama";
$b = "kedua";
[$a, $b] = [$b, $a];
echo $a; // kedua
echo $b; // pertama
Destrukturing Array Asosiatif #
<?php
$user = [
"id" => 42,
"nama" => "Budi Santoso",
"email" => "[email protected]",
"role" => "admin",
];
// Ekstrak key spesifik ke variabel
["nama" => $nama, "email" => $email] = $user;
echo $nama; // Budi Santoso
echo $email; // [email protected]
// Sangat berguna untuk hasil query database
$rows = $pdo->query("SELECT id, nama, email FROM users")->fetchAll();
foreach ($rows as ["id" => $id, "nama" => $nama, "email" => $email]) {
echo "[$id] $nama — $email\n";
}
Destrukturing dalam Fungsi #
<?php
// Fungsi yang mengembalikan multiple value via array
function hitungStatistik(array $data): array
{
return [
"min" => min($data),
"max" => max($data),
"rata" => array_sum($data) / count($data),
"jumlah" => array_sum($data),
];
}
// Destrukturing hasil fungsi
["min" => $min, "max" => $max, "rata" => $rata] = hitungStatistik([10, 20, 30, 40, 50]);
echo "Min: $min, Max: $max, Rata-rata: $rata";
// Min: 10, Max: 50, Rata-rata: 30
Variabel dalam String #
PHP mendukung interpolasi variabel di dalam string berkutip dua. Ada dua sintaks yang perlu dipahami:
<?php
$nama = "Budi";
$produk = ["nama" => "Laptop", "harga" => 15000000];
// Interpolasi sederhana — variabel scalar langsung di dalam string
echo "Halo, $nama!"; // Halo, Budi!
// Interpolasi dengan kurung kurawal — untuk ekspresi yang lebih kompleks
echo "Halo, {$nama}!"; // Halo, Budi! (sama)
echo "Produk: {$produk['nama']}"; // Produk: Laptop
// Interpolasi ekspresi — hanya bisa dengan sintaks ${expr}
$i = 2;
echo "Elemen ke-$i"; // Elemen ke-2
// Yang TIDAK bisa diinterpolasi langsung (butuh concatenation)
echo "Harga: Rp " . number_format($produk['harga']); // fungsi harus di-concat
// ANTI-PATTERN: concatenation berulang yang bisa disederhanakan
$pesan = "Halo " . $nama . ", selamat datang di " . $aplikasi . "!";
// BENAR: interpolasi lebih bersih untuk string yang banyak variabel
$pesan = "Halo, {$nama}, selamat datang di {$aplikasi}!";
Heredoc dan Nowdoc #
Untuk string panjang multi-baris, PHP menyediakan dua sintaks khusus:
<?php
$nama = "Budi";
$total = 150000;
// Heredoc — seperti kutip dua, mendukung interpolasi
$email = <<<EOT
Yth. {$nama},
Terima kasih atas pembelian Anda.
Total yang dibayarkan: Rp {$total}
Salam,
Tim Customer Service
EOT;
echo $email;
// Nowdoc — seperti kutip satu, TIDAK ada interpolasi
$template = <<<'EOT'
Variabel $nama tidak akan diinterpolasi.
Ini teks literal apa adanya.
EOT;
echo $template;
// Output: Variabel $nama tidak akan diinterpolasi.
Heredoc sangat berguna untuk template HTML atau email panjang yang memuat banyak variabel. Nowdoc berguna untuk menyimpan teks yang memang berisi karakter $ secara literal, seperti script atau kode lain.
Ringkasan #
- Semua variabel PHP diawali
$— tidak ada deklarasi tipe, PHP tentukan tipe dari nilai yang di-assign. Variabel bersifat case-sensitive:$namadan$Namaadalah dua variabel berbeda.- Scope fungsi terisolasi — variabel global tidak otomatis tersedia di dalam fungsi. Kirim data lewat parameter, bukan lewat
globalkeyword.- Variabel statis (
static) mempertahankan nilai antar pemanggilan fungsi — berguna untuk counter dan memoization sederhana.- Pass-by-value adalah default — fungsi menerima salinan, modifikasi di dalam fungsi tidak mempengaruhi variabel asli. Gunakan
&untuk reference jika memang dibutuhkan.- Selalu
unset()reference setelahforeach &— tanpanya, variabel reference masih menunjuk ke elemen terakhir array dan bisa menyebabkan bug halus.isset()vsempty()vsis_null()— paham perbedaannya:isset()cek keberadaan dan bukan-null;empty()cek falsy;is_null()cek null persis.- Destrukturing
[]— cara elegan mengekstrak nilai dari array ke variabel terpisah, mendukung array terindeks maupun asosiatif.- Interpolasi string — gunakan
"$var"atau"{$var}"di dalam string berkutip dua alih-alih concatenation berulang untuk kode yang lebih bersih.- Hindari variabel variabel (
$$var) — gunakan array asosiatif sebagai gantinya; lebih jelas, lebih aman, dan lebih mudah di-debug.