Fungsi akan jauh lebih berguna jika hasil kerjanya bisa dibawa pulang ke pemanggil. Di sinilah peran return value: sebuah fungsi mengolah masukan, lalu menyerahkan keluarannya lewat pernyataan return untuk disimpan di variabel, dicetak, atau dipakai dalam ekspresi lain. Pada Chapter ini kita membahas perilaku return secara menyeluruh — mulai dari fungsi yang tampak tidak mengembalikan apa pun hingga pola lanjutan seperti pengembalian array berpasangan dan pengembalian oleh referensi.

return Menghentikan Eksekusi Fungsi #

Pernyataan return melakukan dua hal sekaligus: menyerahkan nilai ke pemanggil dan menghentikan eksekusi fungsi pada saat itu juga. Baris-baris setelah return yang terpicu tidak akan pernah dieksekusi. Sifat ini membuat pola guard clause populer: kondisi penolak diperiksa di awal fungsi, dan sisa tubuh fungsi hanya berisi alur utama tanpa indentasi bersarang.

php
<?php
function cekKelayakan(int $umur): string
{
    if ($umur < 17) {
        return "Ditolak: umur $umur belum mencukupi";
    }

    return "Diterima: umur $umur memenuhi syarat";
}

echo cekKelayakan(15) . "\n";
echo cekKelayakan(21) . "\n";

Output yang Dihasilkan:

text
Ditolak: umur 15 belum mencukupi
Diterima: umur 21 memenuhi syarat

Mari kita amati alurnya langkah demi langkah:

  1. Baris 3-5: guard clause memeriksa $umur < 17; jika bernilai true, return segera keluar dari fungsi membawa string penolakan.
  2. Baris 7: return kedua hanya tercapai bila guard tidak terpicu — inilah jalur utama fungsi.
  3. Baris 10-11: pemanggilan dengan 15 memperoleh jawaban Ditolak, sedangkan 21 memperoleh Diterima.

Pemakaian dua return atau lebih seperti ini tetap sehat selama bentuknya guard-style di awal atau percabangan yang jelas. Yang perlu dihindari adalah puluhan jalur return yang saling menjalin di tengah loop dalam, karena membuat alur fungsi sulit diikuti.

Fungsi Tanpa return Menghasilkan null #

Tidak semua fungsi wajib memiliki return. Fungsi yang hanya menghasilkan efek samping — mencetak, menyimpan berkas, mengirim data — sering berakhir tanpa pernyataan return sama sekali. PHP tidak error dalam kasus ini; fungsi semacam itu secara implisit mengembalikan null.

php
<?php
function catatAktivitas(string $aktivitas)
{
    echo "[LOG] $aktivitas\n";
}

$hasil = catatAktivitas("Aplikasi dimulai");
var_dump($hasil);

Output yang Dihasilkan:

text
[LOG] Aplikasi dimulai
NULL

Baris echo di dalam fungsi tetap berjalan seperti biasa dan mencetak catatan log. Setelah tubuh fungsi habis, PHP menyerahkan NULL kepada pemanggil — terlihat dari var_dump($hasil) yang mencetak NULL. Nilai null ini memang tidak berguna sebagai data, jadi membaca hasil fungsi efek-samping biasanya tidak dilakukan; namun memahami perilaku ini penting karena banyak bug pemula berawal dari asumsi bahwa fungsi “pasti mengembalikan sesuatu”.

Mengembalikan Dua Nilai dengan Pola [nilai, error] #

return hanya bisa membawa satu nilai — tetapi satu nilai itu boleh berupa array yang menampung beberapa data. Pola yang lazim dipakai sebelum era exceptions meluas adalah mengembalikan array dua elemen: [nilai, null] saat sukses dan [null, pesanError] saat gagal. Pola ini masih sering dijumpai di library dan API PHP, misalnya pada mysqli lama atau fungsi preg_match() yang mengembalikan status plus hasil.

php
<?php
function cariPengguna(int $id): array
{
    $pengguna = [
        1 => "Budi",
        2 => "Siti",
    ];

    if (!isset($pengguna[$id])) {
        return [null, "Pengguna dengan ID $id tidak ditemukan"];
    }

    return [$pengguna[$id], null];
}

$hasil = cariPengguna(1);
if ($hasil[1] === null) {
    echo "Sukses: {$hasil[0]}\n";
} else {
    echo "Gagal: {$hasil[1]}\n";
}

$hasil = cariPengguna(99);
if ($hasil[1] === null) {
    echo "Sukses: {$hasil[0]}\n";
} else {
    echo "Gagal: {$hasil[1]}\n";
}

[$nama, $error] = cariPengguna(2);
echo "Hasil destrukturisasi: $nama\n";

Output yang Dihasilkan:

text
Sukses: Budi
Gagal: Pengguna dengan ID 99 tidak ditemukan
Hasil destrukturisasi: Siti

Ada beberapa hal penting dalam contoh di atas:

  1. Baris 9-11: saat ID tidak ditemukan, fungsi mengembalikan [null, pesan]; elemen pertama kosong karena tidak ada nilai yang pantas dilaporkan.
  2. Baris 13: saat sukses, posisinya dibalik — [$pengguna[$id], null] — sehingga pemanggil cukup memeriksa elemen kedua untuk mengetahui status.
  3. Baris 30 ([$nama, $error] = cariPengguna(2);): list destructuring memecah array kembalian langsung ke dua variabel, cara ringkas yang akan kita dalami saat membahas array pada Section Arrays dan Collections.

Mengembalikan Referensi #

Secara bawaan, return menyerahkan salinan nilai — pemanggil mengubah salinannya tanpa memengaruhi data di dalam fungsi. PHP juga memungkinkan fungsi mengembalikan referensi (alias ke lokasi data yang sama) dengan menambahkan tanda & pada nama fungsi saat definisi dan pada variabel penerima saat pemanggilan. Untuk melihatnya bekerja, kita perlu variabel yang bertahan di dalam fungsi; kata kunci static di bawah menciptakan variabel semacam itu (kita bedah tuntas di Chapter Variable Scope).

php
<?php
function &dapatkanCounter(): int
{
    static $counter = 0;
    return $counter;
}

$counter =& dapatkanCounter();
$counter = 100;

echo "Nilai counter kini: " . dapatkanCounter() . "\n";

Output yang Dihasilkan:

text
Nilai counter kini: 100

Terdapat dua tanda & yang bekerja bersama di sini. Deklarasi function &dapatkanCounter() menyatakan bahwa fungsi menyerahkan referensi ke $counter, bukan salinannya. Lalu $counter =& dapatkanCounter() mengikat variabel $counter milik pemanggil ke lokasi memori yang sama; penugasan $counter = 100 kini mengubah nilai asli, sehingga pemanggilan berikutnya melaporkan 100. Jika salah satu & dihilangkan, salinan yang berpindah tangan dan hasilnya tetap 0.

Ringkasan #

return menyerahkan satu nilai dan langsung mengakhiri eksekusi fungsi; tanpa return, fungsi mengembalikan null. Beberapa nilai dapat dibawa bersama lewat array — pola [nilai, error] adalah contoh yang bertahan lama di ekosistem PHP — dan & memungkinkan pengembalian referensi untuk kasus khusus. Nilai kembalian yang baik membuat fungsi mudah dikomposisikan; agar kontraknya semakin tegas, pada Chapter berikutnya kita menyatakan return type secara eksplisit.

Referensi #