Pada Chapter sebelumnya kita melihat fungsi mengembalikan apa saja — angka, string, array, bahkan null diam-diam. Pemanggil tidak punya cara memastikan jenis nilai yang akan diterima selain membaca isi fungsi baris per baris. PHP 7 memperkenalkan return type declaration: anotasi setelah tanda kurung yang menyatakan jenis nilai kembalian, dan interpreter akan menolak nilai yang menyimpang. Pada Chapter ini kita pelajari seluruh jenis return type — dari int sampai never — beserta aturan koersi dan error yang menyertainya.
Menyatakan Return Type Dasar #
Return type ditulis setelah tanda kurung penutup parameter, dipisahkan tanda titik dua (:). Setelah dinyatakan, setiap jalur return di dalam fungsi harus membawa nilai yang sesuai. Tipe dasar yang tersedia sama dengan tipe nilai PHP: int, float, string, bool, dan array.
<?php
function hitungLuasPersegi(float $sisi): float
{
return $sisi * $sisi;
}
function buatLabel(string $nama, float $angka): string
{
return "$nama: " . number_format($angka, 2, ",", ".") . " m2";
}
function ambilDaftarTag(): array
{
return ["php", "fungsi", "return-type"];
}
echo buatLabel("Luas ruangan", hitungLuasPersegi(4.5)) . "\n";
print_r(ambilDaftarTag());Output yang Dihasilkan:
Luas ruangan: 20,25 m2
Array
(
[0] => php
[1] => fungsi
[2] => return-type
)Fungsi pertama menyatakan : float karena hasil perkalian dua bilangan desimal selalu berupa float; fungsi kedua menyatakan : string karena number_format() menghasilkan string berformat Indonesia (20,25); fungsi ketiga menyatakan : array tanpa parameter sama sekali — return type berdiri sendiri dan tidak bergantung pada masukan. Pemanggil kini bisa mempercayai bentuk keluaran tanpa memeriksa implementasi; editor dan alat analisis statis pun memanfaatkan informasi ini.
Return Type Nullable dengan ?int #
Kadang fungsi wajar mengembalikan “tidak ada hasil” — pencarian yang gagal, data yang belum ada. Return type nullable ditulis dengan tanda tanya di depan tipe, misalnya ?int, yang berarti nilai kembalian boleh berupa integer atau null. Tanpa tanda tanya, mengembalikan null dari fungsi bertipe int akan memicu TypeError.
<?php
function cariKodePos(string $kota): ?int
{
$daftar = [
"Bandung" => 40115,
"Jakarta" => 10110,
];
return $daftar[$kota] ?? null;
}
var_dump(cariKodePos("Bandung"));
var_dump(cariKodePos("Surabaya"));Output yang Dihasilkan:
int(40115)
NULLOperator ?? pada baris return mengembalikan kode pos jika kota ditemukan, dan null jika tidak — keduanya sah untuk ?int. Pemanggil bertanggung jawab memeriksa hasil null sebelum menggunakannya sebagai angka, misalnya dengan if ($kodePos !== null). Pola “kembalikan null untuk tidak-ditemukan” seperti ini sangat umum di fungsi pencarian pada library PHP.
Return Type void dan never #
Dua return type istimewa justru menyatakan bahwa fungsi tidak mengembalikan nilai. void berarti fungsi hanya menghasilkan efek samping dan boleh memakai return; tanpa nilai — tetapi return $sesuatu; adalah TypeError. never lebih ekstrem lagi: fungsi harus menghentikan eksekusi dengan melempar exception atau memanggil exit(), sehingga baris kode setelah pemanggilannya dijamin tidak pernah berjalan.
<?php
function cetakJudul(string $judul): void
{
echo "== $judul ==\n";
return;
}
cetakJudul("Belajar Return Type");
$hasil = cetakJudul("Uji NULL");
var_dump($hasil);Output yang Dihasilkan:
== Belajar Return Type ==
== Uji NULL ==
NULLPada contoh di atas, return; tanpa nilai bersifat opsional — tubuh fungsi yang habis juga mengakhiri fungsi void secara wajar. var_dump($hasil) membuktikan bahwa fungsi void menyerahkan NULL ke pemanggil, sama seperti fungsi tanpa return pada Chapter sebelumnya; bedanya, kini kontrak “tidak ada nilai balik” tercetak jelas di deklarasi.
Berikutnya never dalam aksi, membungkus throw agar pemanggil tidak perlu memeriksa hasil yang mustahil ada:
<?php
function hentikanProgram(string $alasan): never
{
throw new RuntimeException($alasan);
}
function prosesPesanan(int $jumlah): string
{
if ($jumlah <= 0) {
hentikanProgram("Jumlah pesanan tidak valid: $jumlah");
}
return "Memproses $jumlah pesanan";
}
echo prosesPesanan(3) . "\n";
try {
echo prosesPesanan(-1) . "\n";
} catch (RuntimeException $e) {
echo "Dihentikan: " . $e->getMessage() . "\n";
}Output yang Dihasilkan:
Memproses 3 pesanan
Dihentikan: Jumlah pesanan tidak valid: -1RuntimeException adalah class exception bawaan PHP; throw menghentikan alur normal dan menyerahkan kendali ke blok catch terdekat (mekanisme exceptions kita bahas tuntas pada Section Error Handling). Karena hentikanProgram() dinyatakan : never, PHP memahami bahwa prosesPesanan(-1) tidak akan pernah mencapai return — cocok untuk fungsi penolak, redirect, atau exit() pada CLI.
Koersi Nilai Kembalian di Weak Mode #
Sama seperti parameter, nilai kembalian juga dikoersi otomatis saat tipenya berbeda namun “kompatibel” — mode bawaan ini disebut weak mode. Float bertitik nol dikonversi ke integer tanpa gejala, integer menjadi string saat dibutuhkan, dan string numerik seperti "5" diterima untuk return type int.
<?php
function keInt(float $nilai): int
{
return $nilai;
}
function keString(int $nomor): string
{
return $nomor;
}
echo keInt(3.0) . "\n";
echo keString(7) . "\n";Output yang Dihasilkan:
3
7keInt(3.0) mengembalikan integer 3 — nilai float yang kehilangan pecahan nol dianggap aman. keString(7) menghasilkan string "7" yang dicetak sama. Koersi senyap seperti ini nyaman, tetapi menyimpan jebakan saat pecahannya tidak nol.
TypeError saat Melanggar Return Type #
Jika nilai kembalian tidak bisa didamaikan dengan return type — misalnya string acak dikembalikan dari fungsi bertipe int — PHP melempar TypeError yang menghentikan program. Mari kita lihat bentuk error-nya secara nyata; jalankan berkas berikut dan perhatikan exit code-nya.
<?php
function hitungDiskon(int $persen): int
{
return "sepuluh persen";
}
echo hitungDiskon(10);Output yang Dihasilkan:
Fatal error: Uncaught TypeError: hitungDiskon(): Return value must be of type int, string returned in /home/z/my-project/php-course/content/php/fungsi/return-types/.verify_tmp.php:4
Stack trace:
#0 /home/z/my-project/php-course/content/php/fungsi/return-types/.verify_tmp.php(7): hitungDiskon(10)
#1 {main}
thrown in /home/z/my-project/php-course/content/php/fungsi/return-types/.verify_tmp.php on line 4Pesan Return value must be of type int, string returned menyebut fungsi pelanggar, tipe yang dijanjikan, dan tipe yang sebenarnya dikembalikan; program berhenti dengan exit code 255. Bagian path berkas dan nomor baris pada pesan akan sesuai dengan lokasi berkas di komputer Anda. Error sekeras ini justru kabar baik: kesalahan data tertangkap di titik kejadian, bukan menjalar diam-diam ke fungsi lain.
Return Type Berbasis Class #
Untuk fungsi yang bekerja dengan object, return type bisa berupa nama class — baik class buatan sendiri maupun class bawaan seperti DateTimeImmutable. Di dalam class, PHP menyediakan tipe khusus: self berarti “class tempat method ini didefinisikan”, parent berarti “class induknya”, dan static berarti “class yang benar-benar memanggil method” (penting saat pewarisan). Kita baru membahas class secara mendalam pada Section Object-Oriented Programming, jadi cukup kenali bentuknya di sini.
<?php
class Produk
{
public function namaPaket(): string
{
return "Paket Produk";
}
public function salinan(): static
{
return new static();
}
}
class Buku extends Produk
{
public function namaPaket(): string
{
return "Buku - " . parent::namaPaket();
}
public function salinanSelf(): self
{
return new self();
}
}Method salinan() dijamin mengembalikan instance dari class pemanggil — new static() di dalam Produk menghasilkan Produk, tetapi saat dipanggil dari Buku menghasilkan Buku. Sebaliknya salinanSelf() selalu mengembalikan Buku karena self terikat pada class tempat ia ditulis. Perbedaan halus ini baru terasa saat pewarisan berlapis; untuk sekarang, cukup pahami bahwa nama class juga sah menjadi return type.
Ringkasan #
Return type : int, : string, : array, dan kawan-kawannya menjadikan janji fungsi terlihat dari luar; ?T mengizinkan null, void menyatakan tidak ada nilai balik, dan never menjamin fungsi tidak pernah kembali. Weak mode mengkoersi nilai yang kompatibel — dengan deprecation untuk float yang kehilangan pecahan — sementara pelanggaran sejati berakhir TypeError. Aturan yang sama berlaku pada sisi masukan; pada Chapter berikutnya kita terapkan deklarasi tipe pada parameter fungsi.