Fungsi tanpa tipe menerima apa saja: angka, teks, array, bahkan null yang tidak diundang. Kesalahan tipe semacam itu sering tidak terasa saat masuk, lalu meledak jadi bug di tengah tubuh fungsi — jauh dari lokasi kesalahan sebenarnya. Parameter type declaration memindakan penjagaan itu ke pintu masuk: cukup satu anotasi di depan nama parameter, dan PHP akan memeriksa setiap argumen pada setiap pemanggilan. Pada Chapter ini kita memetakan seluruh tipe parameter yang tersedia beserta aturan koersinya.

Parameter Bertipe Skalar #

Tipe skalar — int, float, string, bool — diletakkan sebelum nama parameter, sama seperti posisi tipe pada variabel fungsi di chapter-chapter sebelumnya. Deklarasi ini berlaku untuk semua pemanggilan: argumen yang sesuai diterima, argumen yang menyimpang ditolak di muka pintu.

php
<?php
function hitungDiskon(float $harga, int $persen): float
{
    return $harga * $persen / 100;
}

echo hitungDiskon(150000, 20) . "\n";
echo hitungDiskon("99000", "10") . "\n";

Output yang Dihasilkan:

text
30000
9900

Pada pemanggilan pertama, integer 150000 dikirim ke parameter float $harga dan diterima sebagai 150000.0. Pada pemanggilan kedua, string numerik "99000" dan "10" juga lolos — inilah type coercion di weak mode (mode bawaan PHP) yang akan kita bedah sesaat lagi. Hasil kedua pemanggilan identik secara matematis: 30000 dan 9900.

Koersi Tipe di Weak Mode #

Secara bawaan PHP berusaha mendamaikan tipe argumen dengan tipe parameter selama konversinya dianggap aman. String numerik menjadi angka, integer menjadi float, dan true/false menjadi 1/0. Tabel berikut merangkum hasil uji nyata di PHP 8.4 untuk parameter bertipe int dan float:

Nilai yang dikirimTipe parameterHasil di weak mode
5floatditerima sebagai 5.0 (pelebaran selalu aman)
"99000"intdikoersi menjadi 99000
"5.5"intDeprecated + menjadi 5 (pecahan hilang)
3.7intDeprecated + menjadi 3 (dipotong ke arah nol)
trueintmenjadi 1
"sepuluh"intTypeError, program berhenti
""intTypeError
nullint (non-nullable)TypeError

Perhatikan bahwa sejak PHP 8, string yang bukan angka tidak lagi dikoersi diam-diam menjadi 0 seperti di PHP 7 — kini PHP melempar TypeError. Mari kita lihat wujud error tersebut dari contoh nyata:

php
<?php
function potonganHarga(int $persen): int
{
    return $persen;
}

echo potonganHarga("sepuluh");

Output yang Dihasilkan:

text

Fatal error: Uncaught TypeError: potonganHarga(): Argument #1 ($persen) must be of type int, string given, called in /home/z/my-project/php-course/content/php/fungsi/parameter-types/.verify_tmp.php on line 7 and defined in /home/z/my-project/php-course/content/php/fungsi/parameter-types/.verify_tmp.php:2
Stack trace:
#0 /home/z/my-project/php-course/content/php/fungsi/parameter-types/.verify_tmp.php(7): potonganHarga('sepuluh')
#1 {main}
  thrown in /home/z/my-project/php-course/content/php/fungsi/parameter-types/.verify_tmp.php on line 2

Pesan Argument #1 ($persen) must be of type int, string given menyebut parameter mana yang dilanggar beserta posisi pemanggilannya; baris Stack trace menunjukkan rantai pemanggil sampai titik error, dan program berhenti dengan exit code 255. Path berkas pada pesan akan sesuai lokasi berkas di komputer Anda.

Parameter Nullable dengan ?string #

Parameter bertipe ?string, ?int, dan seterusnya menerima nilai tipe tersebut atau null. Ini berguna untuk data opsional — nama tengah yang boleh kosong, catatan yang boleh tidak ada. Parameter nullable biasanya dipasangkan dengan nilai default null agar pemanggil bisa melewatkannya sepenuhnya.

php
<?php
function sapa(?string $nama, string $sapaan = "Halo"): string
{
    if ($nama === null) {
        return "$sapaan, tamu!";
    }

    return "$sapaan, $nama!";
}

echo sapa("Budi") . "\n";
echo sapa(null) . "\n";
echo sapa(null, "Selamat pagi") . "\n";

Output yang Dihasilkan:

text
Halo, Budi!
Halo, tamu!
Selamat pagi, tamu!

Ketiga pemanggilan sah: "Budi" mengisi parameter bertipe string, null diterima berkat tanda tanya, dan parameter kedua memakai default parameter yang telah kita pelajari sebelumnya. Di dalam fungsi, pemeriksaan $nama === null memisahkan kedua kasus sebelum string diinterpolasi. Perlu dicatat, null juga bisa diizinkan lewat union type string|null — bentuk lengkapnya kita bahas pada Section Tipe Data dan Type System.

Tipe array dan iterable #

Parameter bertipe array hanya menerima array — scalar atau object akan ditolak TypeError, tanpa koersi apa pun. Tipe ini menghapus kebutuhan memeriksa is_array() di awal fungsi. Sementara itu, tipe iterable lebih longgar: menerima array atau object yang bisa di-foreach seperti Generator (kita temui nanti pada pemrograman fungsional).

php
<?php
function rataRata(array $nilai): float
{
    if ($nilai === []) {
        return 0.0;
    }

    return array_sum($nilai) / count($nilai);
}

var_dump(rataRata([80, 90, 70]));
var_dump(rataRata([]));

Output yang Dihasilkan:

text
float(80)
float(0)

Penjagaan $nilai === [] menghindari pembagian nol saat array kosong; fungsi array_sum() dan count() kemudian menghitung rata-rata secara ringkas. Versi iterable dari pola yang sama memakai foreach agar kompatibel dengan sumber data non-array:

php
<?php
function hitungTotal(iterable $nilai): int
{
    $total = 0;
    foreach ($nilai as $n) {
        $total += $n;
    }

    return $total;
}

echo hitungTotal([10, 20, 30]) . "\n";

Output yang Dihasilkan:

text
60

Karena foreach bekerja pada array maupun object Traversable, hitungTotal() siap menerima keduanya tanpa perubahan — total 60 dihasilkan dari array biasa di sini. Pilih array bila fungsi Anda memang memanggil fungsi array seperti array_map(), dan iterable bila cukup mengiterasi.

Tipe callable #

Parameter bertipe callable menerima segala sesuatu yang bisa dipanggil: nama fungsi dalam string, array [$objek, "namaMethod"], closure, hingga arrow function. Di dalam tubuh fungsi, parameter tersebut dipanggil seperti fungsi biasa. Pola ini adalah pintu masuk pemrograman fungsional — fungsi yang menyerahkan sebagian perilakunya kepada pemanggil.

php
<?php
function terapkan(array $data, callable $proses): array
{
    $hasil = [];
    foreach ($data as $item) {
        $hasil[] = $proses($item);
    }

    return $hasil;
}

$nama = ["budi", "siti", "ani"];
$namaBesar = terapkan($nama, "strtoupper");
print_r($namaBesar);

Output yang Dihasilkan:

text
Array
(
    [0] => BUDI
    [1] => SITI
    [2] => ANI
)

String "strtoupper" adalah nama fungsi bawaan PHP; saat dieksekusi, $proses($item) memanggilnya untuk setiap item sehingga seluruh nama menjadi huruf kapital. Mengirim string selain nama fungsi yang ada (misalnya "tidakAda") baru memicu error saat pemanggilan terjadi — validasi callable hanya memeriksa bentuk, bukan keberadaan target. Bentuk callable lain seperti closure kita praktekkan pada Chapter Anonymous Functions.

Tipe object dan Nama Class #

Untuk data berbasis object, tersedia dua tingkat ketegasan. Tipe object menerima object dari class mana pun; nama class seperti DateTimeImmutable hanya menerima instance class tersebut (atau subclass-nya). Class DateTimeImmutable di bawah adalah class bawaan PHP untuk tanggal — kita cukup memakainya tanpa mendefinisikan apa pun.

php
<?php
function formatJadwal(DateTimeImmutable $waktu): string
{
    return $waktu->format("d-m-Y H:i") . " WIB";
}

function sebutClass(object $objek): string
{
    return get_class($objek);
}

$jadwal = new DateTimeImmutable("2026-01-15 08:00:00");
echo formatJadwal($jadwal) . "\n";
echo sebutClass($jadwal) . "\n";

Output yang Dihasilkan:

text
15-01-2026 08:00 WIB
DateTimeImmutable

formatJadwal() menolak selain DateTimeImmutable, sehingga method format() di dalamnya pasti tersedia; sebutClass() menerima object apa pun dan melaporkan nama class-nya lewat get_class(). Di dalam sebuah class, tersedia juga tipe relatif: self berarti “class tempat kode ini berada” dan parent berarti “class induknya” — keduanya sah sebagai tipe parameter:

php
<?php
class Kendaraan
{
    public function bandingkan(self $sendiri): bool
    {
        return $sendiri instanceof Kendaraan;
    }
}

class Mobil extends Kendaraan
{
    public function cocok(parent $lain): bool
    {
        return $lain instanceof Kendaraan;
    }
}

Union Type Secara Singkat #

Kadang parameter memang wajar menerima lebih dari satu tipe: identifier bisa angka atau string, kuantitas bisa int atau float. Union type int|string menyatakan itu dengan satu garis vertikal. Daftar lengkap aturannya — termasuk union dengan null, false, dan tipe class — menjadi bahasan Section Tipe Data dan Type System; di sini kita cukup melihat bentuk dasarnya.

php
<?php
function formatIdentitas(int|string $id): string
{
    if (is_int($id)) {
        return "ID angka: $id";
    }

    return "ID teks: " . strtoupper($id);
}

echo formatIdentitas(42) . "\n";
echo formatIdentitas("abc-123") . "\n";

Output yang Dihasilkan:

text
ID angka: 42
ID teks: ABC-123

Di dalam fungsi, pemeriksaan is_int($id) memisahkan jalur angka dari jalur teks sebelum nilai diproses. Pemanggilan dengan 42 masuk jalur pertama, "abc-123" masuk jalur kedua — keduanya lolos pemeriksaan union.

Ringkasan #

Tipe parameter menjaga pintu masuk fungsi: skalar (int, float, string, bool), struktur (array, iterable), pemanggilan (callable), dan object (object, nama class, self/parent), ditambah bentuk nullable ?T dan union T1|T2. Weak mode mengkoersi nilai yang kompatibel namun menolak string non-numerik sejak PHP 8, dan pelanggaran keras berakhir TypeError. Koersi senyap ini bisa dimatikan sama sekali — pada Chapter berikutnya kita mengaktifkan declare(strict_types=1) dan mengamati bagaimana fungsi yang sama berperilaku berbeda.

Referensi #