Type System Lanjutan — PHP

PHP modern (8.x) punya sistem tipe yang kaya untuk membuat kode lebih aman dan jelas. Nullable types (?Type) — PHP 7.1: function cari(int $id): ?User { //…

Di PHP modern, tipe bisa ditulis langsung di fungsi: tipe apa yang boleh masuk, dan tipe apa yang keluar. Bayangin laci kasir Bu Tini. Ada kotak khusus uang kertas, kotak koin, dan kotak struk, masing-masing berlabel. Kalau ada yang menaruh struk di kotak uang, Bu Tini langsung menolaknya, sebelum salah hitung terjadi. Label di kotak itu type declaration, dan penolakannya TypeError.

🧪 Tebakan cepat: fungsi totalHarga(int $harga, int $jumlah): int dipanggil dengan totalHarga(15000, "2"). Output-nya 30000 atau TypeError? Tebak dulu, jawabannya ada di bagian "strict_types: berhenti menebak".

Fungsi dengan tipe

Fungsi adalah kumpulan kode bernama yang bisa dipanggil berkali-kali. Lesson Fungsi membahasnya lengkap, di sini cukup bentuk dasarnya:

<?php

function totalHarga(int $harga, int $jumlah): int
{
    return $harga * $jumlah;
}

echo totalHarga(15000, 2);
30000

Kalau tipenya gak cocok

Isi form selalu string, jadi $jumlah sering datang sebagai "2". Ini yang terjadi untuk tiap argumen kedua:

Argumen kedua Tanpa strict_types Dengan strict_types
2 30000 30000
"2" 30000, "2" diubah jadi 2 TypeError, string given
"dua" TypeError, string given TypeError, string given
2.5 30000 plus Deprecated TypeError, float given
null TypeError, null given TypeError, null given

Tanpa pengaturan apa pun PHP memakai coercive mode: string yang isinya angka diubah jadi angka. "dua" gak bisa diubah, jadi PHP berhenti:

Fatal error: Uncaught TypeError: totalHarga(): Argument #2 ($jumlah) must be of type int, string given, called in /app/kasir.php on line 8 and defined in /app/kasir.php:3

Baca pesannya dari kiri: fungsi totalHarga(), argumen ke-2 ($jumlah), harusnya int, yang datang string, dipanggil di baris 8, fungsinya ditulis di baris 3.

strict_types: berhenti menebak

<?php
declare(strict_types=1);

function totalHarga(int $harga, int $jumlah): int
{
    return $harga * $jumlah;
}

echo totalHarga(15000, "2");
Fatal error: Uncaught TypeError: totalHarga(): Argument #2 ($jumlah) must be of type int, string given, called in /app/kasir.php on line 9 and defined in /app/kasir.php:4

Nullable ? dan union |

Kasir Bu Tini mencari harga dari kode menu. Kodenya bisa nomor (1) atau teks ("es-teh"), dan kadang gak ketemu:

<?php
function hargaMenu(int|string $kode): ?int
{
    $daftar = [
        1 => 15000,
        "es-teh" => 5000,
    ];

    if (isset($daftar[$kode])) {
        return $daftar[$kode];
    }

    return null;
}

var_dump(hargaMenu(1));
var_dump(hargaMenu("es-teh"));
var_dump(hargaMenu(99));
int(15000)
int(5000)
NULL

== dan ===

var_dump("15000" == 15000);  // bool(true)
var_dump("15000" === 15000); // bool(false)
var_dump(0 == "a");          // bool(false)
var_dump("1" == "01");       // bool(true)

📌 Tipe lain yang akan kamu temui

⚠️ Jebakan yang sering ketemu

TL;DR: Tipe ditulis di fungsi: function totalHarga(int $harga, int $jumlah): int. Tanpa pengaturan PHP mengubah "2" jadi 2 tapi menolak "dua" dan null dengan TypeError, sedangkan declare(strict_types=1); di baris pertama membuat cuma int yang lolos. ?int berarti int atau null (? = nullable), int|string berarti salah satunya (| = union). Fungsi nullable tetap harus return null, dan null dicek dengan === null, bukan echo. == menyamakan tipe dulu ("15000" == 15000 true), === juga mengecek tipe, jadi biasakan ===.

Yang akan kamu pelajari