Type casting mengubah nilai ke tipe lain, tetapi konversi buta sering kali bukan jawaban: meng-cast string "murah" ke integer menghasilkan 0 tanpa protes, dan bug diam-diam pun lahir. Sebelum mengonversi, kita perlu tahu tipe apa yang sedang dipegang. PHP menyediakan dua kelompok alat pemeriksaan tipe saat runtime (type checking): fungsi predikat is_* yang menjawab “apakah nilai ini bertipe X?”, dan fungsi deskriptif gettype()/get_debug_type() yang melaporkan nama tipenya. Pada Chapter ini kita membedah keduanya beserta pola pemakaiannya yang sehat.

Rangkaian Fungsi is_* #

Setiap tipe dasar punya pasangan fungsi pemeriksa: is_int(), is_float(), is_string(), is_bool(), is_null(), is_array(), dan is_object(). Seluruh fungsi tersebut menerima satu nilai dan mengembalikan true atau false — tidak ada yang dilempar, tidak ada yang dikonversi:

php
<?php
function jenis($nilai)
{
    if (is_int($nilai)) {
        return "int";
    }
    if (is_float($nilai)) {
        return "float";
    }
    if (is_string($nilai)) {
        return "string";
    }
    if (is_bool($nilai)) {
        return "bool";
    }
    if (is_null($nilai)) {
        return "null";
    }
    if (is_array($nilai)) {
        return "array";
    }
    if (is_object($nilai)) {
        return "object";
    }
    return "tipe lain";
}

$contoh = [42, 3.14, "php", true, null, [1, 2], new ArrayObject()];
foreach ($contoh as $nilai) {
    echo jenis($nilai), "\n";
}

Output yang Dihasilkan:

text
int
float
string
bool
null
array
object

Fungsi jenis() memeriksa nilai satu per satu dari atas ke bawah dan mengembalikan label tipe pertama yang cocok. Setiap nilai pada array $contoh lolos ke cabang yang berbeda, dan new ArrayObject() di baris terakhir terdeteksi sebagai object. Perhatikan bahwa pemeriksaan is_int() dan is_float() saling terpisah: integer dan float adalah dua tipe yang berbeda, dan is_int(3.0) mengembalikan false.

gettype() dan get_debug_type() #

Bila yang dibutuhkan adalah nama tipenya, gettype() melaporkannya sebagai string. Fungsi get_debug_type() yang hadir sejak PHP 8.0 melakukan hal serupa tetapi dengan nama yang lebih ramah untuk ditampilkan kepada manusia. Perbandingan keduanya:

php
<?php
$contoh = [42, 3.14, "php", true, null, [1, 2], new ArrayObject(), function () {}, tmpfile()];

foreach ($contoh as $nilai) {
    printf("%-10s | %s\n", gettype($nilai), get_debug_type($nilai));
}

Output yang Dihasilkan:

text
integer    | int
double     | float
string     | string
boolean    | bool
NULL       | null
array      | array
object     | ArrayObject
object     | Closure
resource   | resource (stream)

Ada dua keanehan gettype() yang wajib diingat. Pertama, tipe float dilaporkan sebagai "double" — warisan sejarah dari bahasa C yang dipertahankan demi kompatibilitas. Kedua, nilai null dilaporkan dengan huruf kapital "NULL", berbeda dengan "integer" atau "string" yang huruf kecil semua. Sebaliknya, get_debug_type() konsisten huruf kecil ("float", "null", "int", "bool") dan — inilah keunggulan utamanya — melaporkan nama class yang sebenarnya untuk object: ArrayObject dan Closure, bukan sekadar "object".

Untuk resource, kedua fungsi memberi laporan yang lebih spesifik. Resource yang telah ditutup (misalnya berkas yang sudah di-fclose()) dilaporkan sebagai "resource (closed)", dan is_resource() pun mengembalikan false:

php
<?php
$berkas = tmpfile();
fclose($berkas);

var_dump(gettype($berkas), get_debug_type($berkas), is_resource($berkas));

Output yang Dihasilkan:

text
string(17) "resource (closed)"
string(17) "resource (closed)"
bool(false)

Pemeriksaan Khusus: is_scalar, is_iterable, is_callable #

Di luar tujuh tipe dasar, ada tiga pemeriksa yang menjawab pertanyaan lebih luas. Fungsi is_scalar() menanyakan apakah nilai merupakan tipe skalar (int, float, string, bool). Fungsi is_iterable() menanyakan apakah nilai bisa dilalui foreach (array atau object Traversable). Fungsi is_callable() menanyakan apakah nilai bisa dipanggil sebagai fungsi:

php
<?php
var_dump(is_scalar(42), is_scalar("php"), is_scalar([1]), is_scalar(null));

var_dump(is_iterable([1, 2]), is_iterable(new ArrayIterator()), is_iterable("abc"));

var_dump(is_callable("strlen"), is_callable("fungsiTidakAda"), is_callable(function () {}));

Output yang Dihasilkan:

text
bool(true)
bool(true)
bool(false)
bool(false)
bool(true)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)

Mari kita baca ketiga barisnya. Baris pertama: integer dan string adalah skalar, sedangkan array dan null bukan. Baris kedua: array dan ArrayIterator bisa di-foreach, sedangkan string biasa tidak — perilaku berbeda dari beberapa bahasa lain. Baris ketiga: is_callable() menerima nama fungsi sebagai string, menolak nama yang tidak ada, dan menerima closure — ketiga perilaku yang membuat is_callable() menjadi gerbang sebelum memanggil callback secara aman.

Identitas dengan Operator === #

Pemeriksaan tipe paling sederhana justru tidak memakai fungsi apa pun. Operator === membandingkan nilai DAN tipe, sehingga cocok sebagai uji identitas:

php
<?php
var_dump(42 === 42.0);
var_dump("42" === 42);
var_dump("42" == 42);
var_dump(1 === true);
var_dump(null === null);

Output yang Dihasilkan:

text
bool(false)
bool(false)
bool(true)
bool(false)
bool(true)

Perhatikan kontrasnya: 42 === 42.0 bernilai false karena tipenya berbeda meski nilainya sama, sedangkan "42" == 42 bernilai true karena operator == melakukan konversi sebelum membandingkan. Untuk kasus null, $nilai === null adalah bentuk yang lebih disarankan daripada is_null($nilai) — keduanya setara, tetapi perbandingan identitas terbaca sebagai pernyataan niat dan tidak dapat tertukar dengan fungsi lain yang mirip.

Praktik: Pemformat Nilai Berbasis Tipe #

Sebagai penutup, mari gabungkan seluruh alat menjadi satu pola nyata: fungsi yang memformat nilai untuk ditampilkan di laporan, dengan perlakuan berbeda per tipe:

php
<?php
function formatNilai($nilai)
{
    if (is_int($nilai) || is_float($nilai)) {
        return number_format($nilai, 2, ",", ".");
    }
    if (is_string($nilai)) {
        return '"' . $nilai . '"';
    }
    if (is_bool($nilai)) {
        return $nilai ? "ya" : "tidak";
    }
    if (is_null($nilai)) {
        return "(kosong)";
    }
    return "tipe lain";
}

echo formatNilai(1250000), "\n";
echo formatNilai(3.14159), "\n";
echo formatNilai("Budi"), "\n";
echo formatNilai(true), "\n";
echo formatNilai(null), "\n";

Output yang Dihasilkan:

text
1.250.000,00
3,14
"Budi"
ya
(kosong)

Mari kita bedah cabang-cabangnya. Cabang pertama menangkap angka — integer maupun float — dan memformatnya dengan pemisah ribuan gaya Indonesia (1.250.000,00). Cabang kedua membungkus string dengan tanda kutip agar terlihat jelas di laporan. Cabang ketiga menerjemahkan boolean ke “ya”/“tidak”, cabang keempat menampilkan “(kosong)” untuk null, dan cabang terakhir menjadi jaring pengaman untuk array, object, atau tipe lainnya.

Berkas contoh.php pada bagian bawah halaman merangkum contoh-contoh di atas dalam satu program utuh.

Ringkasan #

Fungsi is_* menguji satu tipe secara spesifik, gettype()/get_debug_type() melaporkan nama tipenya, dan === menguji identitas nilai sekaligus tipenya. Ingat keanehan "double" dan "NULL" pada gettype(), serta nama class yang telanjur dilaporkan get_debug_type(). Alat-alat ini memeriksa tipe secara dinamis saat runtime — pada Chapter berikutnya kita berkenalan dengan cara membatasi tipe sejak awal melalui type declaration, dimulai dari tipe yang paling sering dibutuhkan: nilai yang boleh kosong.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

contoh.php

Unduh berkas
php
<?php

// contoh.php — rangkuman Chapter Type Checking dalam satu program utuh.
// Jalankan dengan: php contoh.php

// 1. Rangkaian fungsi is_*
function jenis($nilai)
{
    if (is_int($nilai)) {
        return "int";
    }
    if (is_float($nilai)) {
        return "float";
    }
    if (is_string($nilai)) {
        return "string";
    }
    if (is_bool($nilai)) {
        return "bool";
    }
    if (is_null($nilai)) {
        return "null";
    }
    if (is_array($nilai)) {
        return "array";
    }
    if (is_object($nilai)) {
        return "object";
    }
    return "tipe lain";
}

$contoh = [42, 3.14, "php", true, null, [1, 2], new ArrayObject()];
foreach ($contoh as $nilai) {
    echo jenis($nilai), "\n";
}

// 2. gettype() vs get_debug_type()
echo "\n";
foreach ([42, 3.14, null, new ArrayObject()] as $nilai) {
    printf("%-10s | %s\n", gettype($nilai), get_debug_type($nilai));
}

// 3. Pemeriksaan khusus
echo "\n";
var_dump(is_scalar(42), is_scalar([1]));
var_dump(is_iterable([1, 2]), is_iterable("abc"));
var_dump(is_callable("strlen"), is_callable("fungsiTidakAda"));

// 4. Identitas dengan ===
var_dump(42 === 42.0, "42" === 42, "42" == 42);

// 5. Pemformat nilai berbasis tipe
function formatNilai($nilai)
{
    if (is_int($nilai) || is_float($nilai)) {
        return number_format($nilai, 2, ",", ".");
    }
    if (is_string($nilai)) {
        return '"' . $nilai . '"';
    }
    if (is_bool($nilai)) {
        return $nilai ? "ya" : "tidak";
    }
    if (is_null($nilai)) {
        return "(kosong)";
    }
    return "tipe lain";
}

echo "\n", formatNilai(1250000), "\n";
echo formatNilai("Budi"), "\n";
echo formatNilai(true), "\n";
echo formatNilai(null), "\n";