Tipe Data & Type System

PHP terkenal fleksibel dalam menangani tipe data — kadang terlalu fleksibel hingga menyebabkan bug yang sulit dilacak. Memahami type system PHP adalah kunci menulis kode yang aman dan profesional.

Type Juggling (Konversi Otomatis)

PHP secara otomatis mengubah tipe data berdasarkan konteks penggunaan. Ini disebut Type Juggling:

<?php
// PHP otomatis konversi string → int dalam perhitungan
$hasil = "10" + 5;
echo $hasil;      // 15 (integer)
echo gettype($hasil);  // integer

// Hati-hati! String yang diawali angka ikut dikonversi
$aneh = "3 kucing" + 2;
echo $aneh;  // 5 (PHP ambil angka 3 dari string, abaikan sisanya!)

// String tanpa angka di depan → jadi 0
$bahaya = "kucing" + 2;
echo $bahaya;  // 2 (string "kucing" → 0, lalu 0 + 2 = 2)
WARNING
// Perbandingan longgar (==) dengan type juggling
var_dump(0 == "halo");     // true di PHP 7! (keduanya dianggap 0)
var_dump("" == false);     // true
var_dump("0" == false);    // true
var_dump(null == false);   // true

// ✅ Selalu gunakan perbandingan ketat (===)
var_dump(0 === "halo");    // false ✅ Aman!
var_dump("" === false);    // false ✅ Aman!

Type Casting (Konversi Manual)

Kadang kamu perlu mengubah tipe data secara eksplisit:

<?php
$harga_string = "49999";

// Casting dengan tanda kurung
$harga_int   = (int) $harga_string;     // 49999
$harga_float = (float) $harga_string;   // 49999.0
$harga_bool  = (bool) $harga_string;    // true (string tidak kosong)

// Casting ke string
$angka = 42;
$teks  = (string) $angka;  // "42"

// Casting ke array / object
$user = (object) ['nama' => 'Qis', 'umur' => 20];
echo $user->nama;  // Qis
CastHasilCatatan
(int)IntegerPotong desimal, string → 0 jika bukan angka
(float)FloatSeperti int tapi simpan desimal
(string)StringAngka → text, bool → "1" atau ""
(bool)Boolean0, "", null, [] → false; sisanya true
(array)ArrayObject → array asosiatif
(object)ObjectArray → object dengan property

Type Hints (Parameter Types)

Sejak PHP 7, kamu bisa mendeklarasikan tipe yang diharapkan pada parameter dan return value:

<?php
// ❌ Tanpa type hints: tidak jelas, rawan error
function hitungTotal($harga, $jumlah, $diskon) {
    return ($harga * $jumlah) - $diskon;
}
hitungTotal("abc", null, []);  // Hasil sampah, tapi PHP diam saja 😱

// ✅ Dengan type hints: jelas, error langsung ketahuan
function hitungTotal(float $harga, int $jumlah, float $diskon = 0): float {
    return ($harga * $jumlah) - $diskon;
}
hitungTotal("abc", null, []);  // TypeError! ✅ PHP langsung protes

Tipe yang Bisa Dipakai

<?php
// Tipe skalar
function contoh(
    int $angka,
    float $desimal,
    string $teks,
    bool $benar
): void { /* void = tidak return apa-apa */ }

// Tipe compound
function prosesData(
    array $data,
    callable $callback,
    object $config
): array { return []; }

// Nullable (boleh null)
function cari(int $id): ?array {
    // ?array artinya: return array ATAU null
    return null;
}

// Union types (PHP 8.0+)
function formatHarga(int|float $angka): string {
    return number_format($angka, 0, ',', '.');
}

// Self (untuk class)
class Produk {
    public static function buat(string $nama): self {
        return new self($nama);
    }
}

Strict Types (Mode Ketat)

Secara default, PHP masih melakukan type juggling meski kamu pakai type hints. Untuk memaksa pengecekan ketat, tambahkan declare(strict_types=1):

<?php
// === TANPA strict_types (default) ===
function tambah(int $a, int $b): int {
    return $a + $b;
}
echo tambah("3", "5");  // 8 — PHP diam-diam konversi string → int

// === DENGAN strict_types ===
declare(strict_types=1);  // Harus di baris pertama file!

function tambah(int $a, int $b): int {
    return $a + $b;
}
echo tambah("3", "5");  // ❌ TypeError: Argument #1 must be of type int, string given
echo tambah(3, 5);      // ✅ 8

[!IMPORTANT] strict_types berlaku PER FILE Deklarasi strict_types=1 hanya berlaku di file yang mendeklarasikannya, bukan secara global. Setiap file yang ingin mode ketat harus menambahkannya sendiri.

Kapan Pakai strict_types?

SituasiRekomendasi
Project baru✅ Selalu pakai — lebih aman
File config / helper✅ Pakai — cegah input aneh
Project lama / legacy⚠️ Hati-hati — bisa banyak error
Laravel✅ Sudah otomatis di generated files

Pengecekan Tipe di Runtime

PHP punya fungsi bawaan untuk mengecek tipe data:

<?php
$data = 42;

// Fungsi is_*
is_int($data);      // true
is_float($data);    // false
is_string($data);   // false
is_bool($data);     // false
is_array($data);    // false
is_null($data);     // false
is_numeric($data);  // true (juga true untuk "42")

// gettype() — nama tipe sebagai string
echo gettype($data);      // "integer"
echo gettype(3.14);       // "double" (float)
echo gettype("hello");    // "string"
echo gettype([1,2,3]);    // "array"

// var_dump() — informasi lengkap (tipe + nilai)
var_dump($data);  // int(42)

Validasi Input yang Aman

<?php
// ❌ Rawan: langsung pakai input tanpa cek
$id = $_GET['id'];
$stmt = $pdo->prepare("SELECT * FROM produk WHERE id = ?");
$stmt->execute([$id]);

// ✅ Aman: validasi tipe dulu
$id = $_GET['id'] ?? null;
if (!is_numeric($id) || (int)$id <= 0) {
    http_response_code(400);
    echo "ID tidak valid!";
    exit;
}
$id = (int) $id;  // Cast ke integer setelah validasi

Class Type Hints

Type hints juga bekerja dengan class dan interface:

<?php
class Produk {
    public function __construct(
        public string $nama,
        public float $harga
    ) {}
}

// Fungsi menerima objek Produk
function tampilkanProduk(Produk $produk): string {
    return "{$produk->nama}: Rp " . number_format($produk->harga, 0, ',', '.');
}

$laptop = new Produk('Laptop', 12000000);
echo tampilkanProduk($laptop);  // Laptop: Rp 12.000.000

// Jika kirim bukan Produk → TypeError!
tampilkanProduk("bukan produk");  // ❌ Error

Rangkuman Best Practices

TIP
  1. ✅ Selalu pakai declare(strict_types=1) di file baru
  2. ✅ Tambahkan type hints di semua parameter dan return value
  3. ✅ Gunakan === (ketat), bukan == (longgar) untuk perbandingan
  4. ✅ Validasi dan cast input dari user sebelum diproses
  5. ✅ Gunakan ?Type atau Type|null untuk nilai yang bisa null
  6. ✅ Pakai var_dump() saat debugging untuk lihat tipe + nilai

Latihan

  1. Tambahkan declare(strict_types=1) ke salah satu file PHP di project Toko Online. Apa yang berubah?
  2. Buat fungsi validasiUmur(int $umur): string yang return "Anak", "Remaja", atau "Dewasa" — tes dengan string "17"
  3. Refactor fungsi hitungTotal() di project-mu untuk pakai type hints lengkap

Selanjutnya

Kamu sudah paham cara PHP mengelola tipe data. Lanjut ke Tanggal & Waktu → untuk belajar mengelola DateTime dengan benar.