Menguasai fondasi bahasa PHP: variabel $nama dengan dynamic typing dan strict_types, konstanta define()/const, delapan tipe dasar (int, float, string, bool, null, array, object, callable), serta operator aritmatika, perbandingan, dan logika beserta jebakan type juggling yang umum terjadi.

Sekarang kita masuk ke inti bahasa. Episode ini adalah fondasi dari semua episode berikutnya: variabel, konstanta, tipe data, dan operator. Jika di episode 3 kita belajar "menyalakan mesin", di episode ini kita belajar "mengemudi" — dan keputusan desain PHP seperti dynamic typing akan sangat menentukan cara kalian menulis kode.
Mengapa materi ini penting? Karena 80% bug aplikasi PHP berakar pada pemahaman tipe yang longgar: membandingkan string dengan angka, mengabaikan null, atau asumsi bahwa 0 dan "0" itu sama. Dengan memahami tipe sejak awal, kalian menghindari sekaligus seluruh kelas bug yang biasa menjebak developer pemula.
Semua variabel PHP diawali $ dan dinamis: tidak perlu (dan tidak boleh) mendeklarasikan tipe saat membuat variabel.
<?php
$nama = "Devvnull";
$usia = 5;
$aktif = true;
$saldo = 2500.50;
$minat = ["web", "backend"];
echo $nama . " berusia " . $usia . " tahun\n";
echo "Minat: " . implode(", ", $minat) . "\n";Nama variabel case-sensitive ($Nama berbeda dari $nama) dan bisa mengandung huruf, angka, dan underscore, tetapi tidak boleh diawali angka. $nama{$usia} tidak valid — pola seperti ini justru memakai kurung kurawal dalam string, yang sudah kita hindari.
strict_typesPHP adalah bahasa dynamically typed: tipe variabel ditentukan oleh nilai yang diisi, dan bisa berubah:
$data = "teks"; // string
$data = 42; // kini int
$data = [1, 2]; // kini arrayIni fleksibel, tetapi berbahaya di antarmuka fungsi. Solusi modern: declaration + strict_types. Di episode 5 kita pelajari type declaration; untuk sekarang ingat dua mode:
"5" dipakai sebagai int 5.declare(strict_types=1); di baris pertama file, PHP menolak otomatis konversi dan melempar TypeError.<?php
declare(strict_types=1);Baris ini harus menjadi baris pertama file. Sepanjang series kita akan selalu memakai mode strict untuk kualitas produksi.
define() dan constNilai yang tidak berubah sebaiknya dideklarasikan sebagai konstanta, bukan variabel:
define("APP_NAME", "Devvnull");
const MAX_ITEMS = 100;
const API_BASE_URL = "https://api.example.com";Perbedaan kunci: define() dipanggil saat runtime dan bisa dipakai di dalam kondisi; const dideklarasikan saat kompilasi dan hanya bisa di top-level atau dalam class (episode 7). Sejak PHP 8.3, konstanta class bisa memiliki tipe:
class Settings
{
public const string VERSION = "1.0.0";
}PHP 8.x punya delapan tipe primitif + composite:
| Tipe | Contoh | Catatan |
|---|---|---|
int | 42, -7 | Bilangan bulat, 64-bit |
float | 3.14, 2.5e3 | Bilangan pecahan |
string | "halo" | Teks, UTF-8 |
bool | true, false | Logika |
null | null | Tanpa nilai |
array | [1, 2, 3] | List atau map (episode 6) |
object | new User() | Instance class (episode 7) |
callable | fn($x) => $x * 2 | Fungsi sebagai nilai |
Jenis khusus PHP: union type int|string dan intersection A&B (PHP 8.1+) memungkinkan mengetik lebih presisi. Cek tipe runtime dengan var_dump() atau gettype():
var_dump("5" == 5); // bool(true) — loose comparison
var_dump("5" === 5); // bool(false) — strict comparison$a = 10;
$b = 3;
echo $a + $b, "\n"; // 13
echo $a % $b, "\n"; // 1 (modulo)
echo $a ** $b, "\n"; // 1000 (pangkat, PHP 5.6+)== dan ===Ini jebakan paling klasik PHP:
| Operator | Arti | Contoh |
|---|---|---|
== | loose: nilai sama setelah konversi | "1" == 1 → true |
=== | strict: nilai dan tipe sama | "1" === 1 → false |
!= / !== | negasi dari di atas | — |
<=> | spaceship: -1, 0, 1 | 2 <=> 3 → -1 |
Aturan praktis: selalu pakai === dan !==, kecuali kalian benar-benar sengaja memakai konversi. Aturan ini mencegah bug seperti if ($input == 0) yang bernilai true saat $input adalah "" atau "abc".
Danger
Perbandingan == di PHP pernah menghasilkan perilaku membingungkan, contoh klasik "1e3" == 1000 bernilai true karena string dianggap angka. Di era PHP modern, biasakan === untuk hampir semua perbandingan — dan bila perlu membandingkan angka dari input, konversikan eksplisit dengan (int) atau intval().
$dewasa = true;
$punyaKtp = false;
var_dump($dewasa && $punyaKtp); // false
var_dump($dewasa || $punyaKtp); // true
var_dump(!$dewasa); // falsePerhatikan juga short-circuit: && dan || berhenti mengevaluasi begitu hasilnya pasti. Ini dipakai untuk guard pattern, misal memeriksa objek sebelum mengakses propertinya.
Dua operator penyelamat dari era PHP 7/8 yang wajib dipakai:
$nama = $_GET["nama"] ?? "Anonim"; // fallback saat tidak ada
$kota = $user?->alamat?->kota; // nullsafe chain
$panjang = strlen($nama ?? ""); // gabungan?? (null coalescing) mengembalikan operan kanan bila operan kiri null atau tidak ada. ?-> (nullsafe) menghentikan rantai bila salah satu nilainya null — menghindari error "Call to a member function on null".
0 vs false vs "" — ketiganya falsy; gunakan === saat membedakan.0.1 + 0.2 == 0.3; gunakan epsilon atau bandingkan string desimal.null + warning; selalu inisialisasi atau gunakan ??.declare(strict_types=1) — konversi diam-diam terjadi dan bug muncul jauh di hilir.Inti yang harus dibawa pulang:
$, dynamically typed, dan case-sensitive.declare(strict_types=1); di baris pertama file untuk kualitas produksi.define() vs const; typed class constants sejak PHP 8.3.== vs === — selalu prioritaskan strict.?? dan ?-> untuk menangani kemungkinan null dengan elegan.Di episode 5 selanjutnya kita membangun kendali alur: control flow & fungsi — if/else, switch/match, for/foreach/while, continue/break, lalu mendeklarasikan fungsi dengan parameter bertipe, named arguments, dan variadic. Materi ini akan mengubah kalian dari "menulis skrip" menjadi "menulis program".