Saat program tumbuh besar, menyalin-tempel potongan kode yang sama ke banyak tempat menjadi sumber galat yang sulit dilacak: satu perbaikan harus diulang di sepuluh tempat, dan satu tempat yang terlewat membuat program berperilaku tidak konsisten. Fungsi adalah solusi PHP untuk masalah tersebut — blok kode yang diberi nama, ditulis sekali, lalu dapat dipanggil berkali-kali dari tempat mana pun di program. Pada chapter ini kita mempelajari anatomi fungsi buatan sendiri (user-defined function): cara mendefinisikannya dengan kata kunci function, cara mengembalikan nilai, aturan penamaannya, sampai perilaku urutan definisi yang khas PHP.
Anatomi Fungsi #
Sebuah fungsi didefinisikan dengan kata kunci function, diikuti nama fungsi, tanda kurung, lalu badan fungsi (function body) yang dibungkus sepasang kurung kurawal. Mari kita mulai dari bentuk paling sederhana — fungsi tanpa masukan yang mengembalikan sebuah string:
<?php
function sapaPengguna()
{
return "Halo, selamat belajar PHP!";
}
echo sapaPengguna() . "\n";Output yang Dihasilkan:
Halo, selamat belajar PHP!Mari kita telaah apa yang terjadi pada baris-baris kode di atas:
- Baris 2 (
function sapaPengguna()): kata kuncifunctionmemberi tahu interpreter bahwa kita mendefinisikan fungsi bernamasapaPengguna. Tanda kurung yang kosong menandakan fungsi ini tidak meminta masukan apa pun; tanda kurung tersebut tetap wajib ditulis. - Baris 4 (
return ...;): pernyataanreturnsekaligus menghentikan eksekusi fungsi dan mengirim nilai string tersebut keluar ke pemanggil. - Baris 7 (
echo sapaPengguna() . "\n";): kita memanggil fungsi dengan menuliskan namanya diikuti tanda kurung. Nilai yang dikembalikan fungsi dirangkai dengan"\n"lalu dicetak lewatecho.
Setiap pemanggilan menjalankan badan fungsi dari atas ke bawah seperti kode biasa. Parameter, pemanggilan berulang, dan cara nilai mengalir masuk kita bedah tuntas pada chapter-chapter selanjutnya di section ini.
Mengembalikan Nilai dengan return #
Kata kunci return memainkan dua peran sekaligus: menghentikan eksekusi fungsi pada titik tersebut, dan menyerahkan sebuah nilai kembali ke pemanggil. Nilai kembalian (return value) bisa langsung dipakai dalam ekspresi — disimpan ke variabel, dirangkai dengan string, atau dioperasikan dengan angka. Contoh berikut menghitung total belanja dari dua masukan:
<?php
function hitungTotalBelanja($hargaSatuan, $jumlah)
{
$total = $hargaSatuan * $jumlah;
return $total;
}
echo hitungTotalBelanja(50000, 3) . "\n";
echo hitungTotalBelanja(12500, 2) . "\n";Output yang Dihasilkan:
150000
25000Mari kita bedah contoh di atas baris per baris:
- Baris 2: fungsi
hitungTotalBelanja()kini memiliki dua parameter —$hargaSatuandan$jumlah— di dalam tanda kurung. Parameter adalah variabel penerima yang nilainya diisi oleh pemanggil; aturan lengkapnya kita bahas pada chapter Parameters dan Arguments . - Baris 4: hasil perkalian disimpan ke variabel
$totaldi dalam badan fungsi. - Baris 5:
return $total;mengirim nilai tersebut keluar; setelah baris ini, eksekusi fungsi berhenti. - Baris 8-9: dua pemanggilan dengan pasangan nilai berbeda menghasilkan dua hasil berbeda —
150000dan25000.
Fungsi yang tidak memiliki return tetap sah; PHP menjadikan nilai kembaliannya null. Fungsi seperti itu biasanya dipakai justru karena efek sampingnya, misalnya mencetak sesuatu ke layar:
<?php
function cetakGarisPemisah()
{
echo str_repeat("-", 20) . "\n";
}
cetakGarisPemisah();
echo "Laporan Penjualan\n";
cetakGarisPemisah();Output yang Dihasilkan:
--------------------
Laporan Penjualan
--------------------Fungsi cetakGarisPemisah() tidak mengembalikan nilai apa pun; fungsi tersebut hanya mencetak 20 tanda hubung lewat str_repeat("-", 20) setiap kali dipanggil. Tiga pemanggilan pada baris 7 sampai 9 mengeksekusi efek samping itu secara berurutan, sehingga judul laporan tampil di antara dua garis pemisah.
Aturan dan Konvensi Penamaan #
Nama fungsi mengikuti aturan yang mirip dengan nama variabel, dengan dua perbedaan penting: tanpa awalan $, dan huruf besar-kecil dianggap sama (case-insensitive). Aturan lengkapnya sebagai berikut:
- Hanya boleh memuat huruf, angka, dan garis bawah (
_). - Tidak boleh diawali angka.
- Tidak boleh memakai kata kunci PHP seperti
function,if, ataulist.
Valid: hitungDiskon, buatEmailPengguna, _prosesInternal, prosesData2
Invalid: 2hitungDiskon (diawali angka), hitung-diskon (tanda hubung),
cetak laporan (spasi), list (kata kunci PHP)Konvensi industri menyarankan camelCase untuk nama multi-kata dan awalan kata kerja yang menjelaskan aksi: hitungDiskon(), buatEmailPengguna(), formatRupiah(). Nama entitas domain boleh berbahasa Indonesia, sementara nama teknis umum biasanya tetap Inggris seperti calculateDiscount() atau getUserById(). Hindari awalan dua garis bawah (__) karena dialokasikan untuk fungsi ajaib (magic methods) milik PHP dan ekstensi.
Definisi Fungsi Bisa Muncul Setelah Pemanggilannya #
PHP memproses sebuah berkas skrip dalam dua tahap: tahap penerjemahan (compilation) ketika struktur kode dipindai, lalu tahap eksekusi. Semua fungsi yang didefinisikan tanpa syarat di tingkat atas berkas sudah terdaftar sejak tahap pertama, sehingga pemanggilan boleh ditulis sebelum baris definisinya — perilaku yang sering disebut hoisting:
<?php
echo hitungDiskon(100000) . "\n";
function hitungDiskon($harga)
{
return $harga * 0.1;
}Output yang Dihasilkan:
10000Baris 2 memanggil hitungDiskon() lebih dulu, padahal definisinya baru muncul pada baris 4. Karena definisi tanpa syarat sudah dikumpulkan saat penerjemahan, pemanggilan tersebut berjalan normal dan menghasilkan 10000, yaitu hasil dari 100000 × 0,1.
Ceritanya berbeda untuk fungsi yang didefinisikan di dalam blok bersyarat. Fungsi semacam itu baru terdaftar ketika bloknya benar-benar dieksekusi:
<?php
$modeDemo = true;
if ($modeDemo) {
function jalankanDemo()
{
return "mode demo aktif";
}
}
echo jalankanDemo() . "\n";Output yang Dihasilkan:
mode demo aktifDefinisi jalankanDemo() berada di dalam blok if pada baris 4-9, sehingga fungsi tersebut baru tersedia setelah blok itu dieksekusi dan kondisinya bernilai true. Pemanggilan pada baris 11 aman karena berada setelah blok tersebut; memanggilnya sebelum blok if dijalankan justru memicu fatal error Call to undefined function.
Fungsi Terdefinisi Bersifat Global #
Setelah terdaftar, sebuah fungsi dapat dipanggil dari mana pun di berkas yang sama — termasuk dari dalam fungsi lain — tanpa pernyataan import khusus. Contoh berikut menunjukkan sebuah fungsi yang memanfaatkan fungsi lain sebagai penyusunnya:
<?php
function formatRupiah($angka)
{
return "Rp" . number_format($angka, 0, ",", ".");
}
function tampilkanTotal($hargaSatuan, $jumlah)
{
$total = $hargaSatuan * $jumlah;
return formatRupiah($total);
}
echo tampilkanTotal(150000, 2) . "\n";Output yang Dihasilkan:
Rp300.000Fungsi tampilkanTotal() memanggil formatRupiah() begitu saja pada baris 10. Berbeda dari variabel — yang jangkauannya dibatasi aturan scope dan kita bahas pada chapter Global dan Static Variables
— nama fungsi berlaku global untuk seluruh berkas begitu didefinisikan. Perilaku inilah yang memungkinkan kita menyusun fungsi pembantu kecil lalu merangkainya menjadi fungsi yang lebih besar.
Memeriksa Keberadaan Fungsi #
Kadang kita perlu memastikan dahulu apakah sebuah fungsi tersedia — misalnya fungsi dari ekstensi yang mungkin tidak terpasang di server tertentu — sebelum memanggilnya. Fungsi bawaan function_exists() menerima nama fungsi sebagai string dan mengembalikan true atau false:
<?php
function tampilkanMenu()
{
return "Nasi Goreng Spesial";
}
var_dump(function_exists('tampilkanMenu'));
var_dump(function_exists('TAMPILKANMENU'));
var_dump(function_exists('menuTidakAda'));
echo TAMPILKANMENU() . "\n";Output yang Dihasilkan:
bool(true)
bool(true)
bool(false)
Nasi Goreng SpesialTiga baris var_dump pada baris 7-9 menghasilkan true, true, dan false: fungsi tampilkanMenu ada, ejaan huruf besar TAMPILKANMENU tetap dianggap ada, sedangkan menuTidakAda memang tidak pernah kita definisikan. Baris 11 membuktikan hal yang sama lewat pemanggilan langsung — PHP menemukan tampilkanMenu() meski kita menulis TAMPILKANMENU().
Nama Duplikat Ditolak Saat Penerjemahan #
Satu nama hanya boleh dipakai satu fungsi. Karena ejaan besar-kecil diabaikan, mendefinisikan prosesData() dua kali — termasuk dengan kapitalisasi berbeda seperti prosesdata() — membuat PHP menolak seluruh berkas sebelum eksekusi dimulai:
<?php
function prosesData()
{
return "versi pertama";
}
function prosesData()
{
return "versi kedua";
}Output yang Dihasilkan:
Fatal error: Cannot redeclare function prosesData() (previously declared in /home/z/my-project/php-course/content/php/fungsi/mendefinisikan-fungsi/.verify_tmp.php:2) in /home/z/my-project/php-course/content/php/fungsi/mendefinisikan-fungsi/.verify_tmp.php on line 7Pesan Cannot redeclare function muncul karena kedua definisi sama-sama berada di tingkat atas tanpa syarat, sehingga bentroknya terdeteksi pada tahap penerjemahan. PHP juga menunjukkan dua lokasi sekaligus: deklarasi pertama pada baris 2 dan deklarasi kedua yang menolak pada baris 7.
Ringkasan #
Kini kita mampu mendefinisikan fungsi dengan function, mengirim nilai keluar dengan return, menamai fungsi sesuai konvensi, dan memahami kapan sebuah definisi sudah tersedia — sekaligus mengapa nama duplikat ditolak. Fungsi yang terdefinisi baru benar-benar berguna setelah kita memanggilnya dengan benar, dan pemanggilan memiliki aturan jumlah serta urutan argumen yang perlu dipahami. Chapter berikutnya membedah mekanisme pemanggilan fungsi secara menyeluruh.