Ini adalah pembahasan fungsi bagian ke-3 dari seri tutorial belajar PHP 7. Kita telah mempelajari tentang fungsi mulai dari cara pendeklarasiannya, cara memanggilnya, parameter pada fungsi, fungsi anonim, callback dan arrow function.
Pada pertemuan kali ini, yang akan kita pelajari adalah mengenai fungsi rekursif.
Apa itu Fungsi Rekursif?
Kita telah menyinggung tentang fungsi rekursif pada pembahasan konsep perulangan pada PHP.
Fungsi rekursif adalah metode perulangan yang terjadi akibat pengeksekusian suatu fungsi yang mana fungsi tersebut memanggil dirinya sendiri. Bisa jadi ia terus memanggil dirinya sendiri tanpa batas, atau mungkin dia akan berhenti jika kondisi tertentu terpenuhi.
Ilustrasinya adalah: seperti anda memiliki 2 buah cermin. Anda letakkan kedua cermin tersebut sedemikian rupa hingga saling berhadapan. Lalu anda coba berdiri di depannya, dan ya! Anda akan melihat pantulan diri anda tidak terbatas.
Ilustrasi yang lainnya adalah: PC anda sedang di-remote oleh PC lain. Lalu anda meremote PC yang sedang meremote PC anda, al-hasil anda akan melihat PC anda berkali-kali tanpa ujung seperti pada gambar berikut:
Pendeklarasian Fungsi Rekursif
Tidak ada cara khusus dalam pendeklarasian fungsi rekursif. Ia hanyalah fungsi biasa. Sama saja apakah ia adalah fungsi yang mengembalikan sebuah nilai atau tidak.
Yang membedakan adalah: ia akan memanggil dirinya sendiri sehingga terjadilah suatu perulangan.
Contoh:
<?php
function tampilkanHaloDunia () {
echo "Halo dunia! <br>";
tampilkanHaloDunia();
}
# panggil fungsi tampilkanHaloDunia();
tampilkanHaloDunia();
Jika kode program di atas dijalankan, ia akan menampilkan teks “Halo dunia!" sebanyak tak terbatas.
Dan ia tentu saja akan membuat komputer anda hank. Jadi, jangan coba-coba dilakukan, ya!
Menampilkan Angka 1-100
Untuk menampilkan angka 1 sampai 100, kita bisa dengan mudah menggunakan perulangan for
seperti berikut:
<?php
for ($i = 1; $i <= 100; $i++) {
echo "Perulangan ke-{$i} <br>";
}
Akan tetapi jika anda ingin menggunakan konsep fungsi rekursif untuk menjalankan tugas yang sama, anda perlu sedikit berfikir.
Pertama, anda buat fungsinya dulu, fungsi biasa.
<?php
function tampilkanAngka ($i) {
echo "Perulangan ke-{$i} <br>";
}
Jika anda memanggil fungsi tampilkanAngka()
di atas, fungsi tersebut hanya akan menampilkan teks sebanyak satu kali saja.
Sekarang, kita jadikan ia sebagai fungsi rekursif.
Kita beri 2 parameter tambahan, yaitu parameter $jumlah
untuk mengetahui berapa jumlah perulangan yang akan dilakukan, dan yang kedua adalah parameter $indeks
untuk mengetahui sekarang sudah perulangan ke berapa.
Untuk parameter $indeks
kita beri nilai default dengan angka 1
.
<?php
function tampilkanAngka (int $jumlah, int $indeks = 1) {
echo "Perulangan ke-{$indeks} <br>";
# panggil diri sendiri selama $indeks <= $jumlah
if ($indeks < $jumlah) {
tampilkanAngka($jumlah, $indeks + 1);
}
}
Lalu panggil fungsi tampilkanAngka
dengan memasukkan satu parameter saja yaitu parameter $jumlah
.
<?php
tampilkanAngka(20);
Perhatikan alur perjalanan program
Sekarang untuk menguji pemahaman, kita coba balik kode program pada fungsi tampilkanAngka
.
Jika kita melakukan proses rekursif setelah perintah echo
, sekarang kita balik: kita lakukan proses rekursif terlebih dahulu, setelah itu kita lakukan perintah echo
.
Seperti ini:
<?php
function tampilkanAngka (int $jumlah, int $indeks = 1) {
# panggil diri sendiri selama $indeks <= $jumlah
if ($indeks < $jumlah) {
tampilkanAngka($jumlah, $indeks + 1);
}
echo "Perulangan ke-{$indeks} <br>";
}
Coba panggil fungsi tampilkanAngka()
tersebut, lalu cek bagaimana output yang dihasilkan.
Kita mendapatkan output terbalik bukan?
Perulangan ke-20
Perulangan ke-19
Perulangan ke-18
Perulangan ke-17
...
Perulangan ke-4
Perulangan ke-3
Perulangan ke-2
Perulangan ke-1
Itu terjadi karena:
- Ketika fungsi
tampilkanAngka
dipanggil pertama kali, ia akan langsung memanggil dirinya sendiri. - Ketika ia dipanggil untuk ke-2 kalinya, ia juga langsung memanggil dirinya sendiri.
- Ia terus melakukan hal yang sama sampai nilai
$indeks
= nilai$jumlah
alias bernilai20
. - Baru setelah rantai paling akhir tidak lagi memanggil dirinya sendiri, ia akan mulai menampilkan angka
20
. - Setelah rantai paling akhir selesai menampilkan angka
20
, maka proses yang ke-19 pun dianggap telah selesai dari proses rekursif, dan ia akan mulai meng-echo
angka 19. - Begitu seterusnya hingga kembali ke perulangan yang pertama.
Masih agak bingung?
Kalau masih agak bingung, silakan ubah kode program di atas menjadi seperti ini:
<?php
function tampilkanAngka (int $jumlah, int $indeks = 1) {
echo "<strong style='color: green'>
Sebelum memanggil diri sendiri [{$indeks}]
</strong><br>";
# panggil diri sendiri selama $indeks <= $jumlah
if ($indeks < $jumlah) {
tampilkanAngka($jumlah, $indeks + 1);
} else {
echo "<strong style='color: red'>
Proses terakhir.
</strong><br>";
}
echo "<strong style='color: blue'>
Sebelum memanggil diri sendiri [{$indeks}]
</strong><br>";
}
Sekarang saya hanya panggil dengan parameter $jumlah = 5
agar tidak terlalu outputnya lebih ringkas:
<?php
tampilkanAngka(5);
Output:
Berikut ini adalah output yang saya hasilkan:
Sampai sini, sudah mulai jelas bagaimana proses dan alur fungsi rekursif bekerja.
Contoh Kasus Faktorial
Selanjutnya kita coba contoh kasus paling populer dalam penggunakan metode perulangan rekursif.
Kasus tersebut adalah kasus pemecahan faktorial. Dimana faktorial dari n sama dengan n * faktorial(n-1)
.
Misalkan faktorial dari angka 5, maka kita bisa sederhanakan caranya seperti ini:
faktorial(5) = 5 * faktorial(4)
faktorial(4) = 4 * faktorial(3)
faktorial(3) = 3 * faktorial(2)
faktorial(2) = 2 * faktorial(1)
faktorial(1) = 1
Hasil di atas sama dengan:
faktorial 5 = 5 * 4 * 3 * 2 * 1
# hasil = 120
Penyelesaian
Dengan rumus seperti di atas, kita bisa mulai memecahkannya dengan fungsi rekursif.
Kita mulai dulu fungsinya secara sederhana seperti berikut:
<?php
function faktorial ($n) {
echo "faktorial({$n}) = faktorial(" . ($n - 1) . ") <br>";
if ($n > 2) {
faktorial($n - 1);
}
}
# panggil
faktorial(5);
Ia akan menghasilkan output:
faktorial(5) = faktorial(4)
faktorial(4) = faktorial(3)
faktorial(3) = faktorial(2)
faktorial(2) = faktorial(1)
Setelah kita berhasil mendapatkan perulangan yang benar, kita ubah fungsi faktorial
di atas dengan mengembalikan suatu nilai seperti berikut:
<?php
function faktorial ($n) {
if ($n > 2) {
return $n * faktorial($n - 1);
} else {
return $n;
}
}
# lalu panggil fungsi faktorial
$hasil = faktorial(5);
echo $hasil;
Jika anda menjalankan program di atas lalu output hasilnya adalah 120
, berarti program anda telah berjalan dengan benar.
Silakan ubah parameter $n
untuk memeriksa apakah memang fungsi faktorial
yang anda lakukan memang betul-betul berfungsi seperti yang diinginkan.
Contoh Kasus Menu Bertingkat Tak Terbatas
Di bawah ini saya memiliki variabel $menu
. Ia adalah gabungan antara array terindeks dan array asosiatif multidimensi. Dikatakan multidimensi karena ia adalah suatu array yang memiliki array lain di dalamnya.
Untuk penjelasan lebih lanjut silakan lihat pembahasan tentang array multidimensi.
Silakan perhatikan kode program di bawah. Karena selanjutnya kita akan coba menampilkan semua item dari array $menu
menggunakan fungsi rekursif.
<?php
$menu = [
[
"nama" => "Beranda"
],
[
"nama" => "Berita",
"subMenu" => [
[
"nama" => "Olahraga",
"subMenu" => [
[
"nama" => "Bola"
],
[
"nama" => "Bulu Tangkis"
]
]
],
[
"nama" => "Politik"
],
[
"nama" => "Manca Negara"
]
]
],
[
"nama" => "Tentang"
],
[
"nama" => "Kontak"
],
];
Pertama kita buat dulu fungsi untuk menampilkan array utama.
<?php
function tampilkanMenuBertingkat (array $menu) {
echo "<ul>";
foreach ($menu as $key => $item) {
echo "<li>{$item['nama']}</li>";
}
echo "</ul>";
}
Jika kita panggil fungsi di atas:
<?php
tampilkanMenuBertingkat($menu);
Kita akan dapatkan hasil seperti ini:
- Beranda
- Berita
- Tentang
- Kontak
Sekarang kita buat fungsi di atas menjadi rekursif dengan memanggil dirinya sendiri ketika suatu item dari menu memiliki attribut subMenu
.
<?php
function tampilkanMenuBertingkat (array $menu) {
echo "<ul>";
foreach ($menu as $key => $item) {
echo "<li>{$item['nama']}</li>";
# periksa apakah ia memiliki atribut subMenu
# dan apakah attribut tersebut memiliki isi
if (@$item['subMenu'] && count($item['subMenu'])) {
# jika ia panggil diri sendiri
tampilkanMenuBertingkat($item['subMenu']);
}
}
echo "</ul>";
}
Kita coba jalankan lagi dan… ya! Kita berhasil mendapatkan hasil seperti ini:
- Beranda
- Berita
- Olahraga
- Bola
- Bulu Tangkis
- Politik
- Manca Negara
- Olahraga
- Tentang
Anda bisa mengubah-ubah variabel $nama
untuk mencoba apakah memang fungsi rekursif yang kita buat tersebut sudah berfungsi dengan benar.
Pembahasan Selanjutnya
Dengan selesainya tutorial ini, berarti kita telah selesai dengan pembahasan Fungsi pada PHP.
Pada pembahasan selanjutnya, kita akan membahas tentang memanipulasi string lalu setelahnya akan membahas bekerja dengan array. Insyaallah.
Jika anda merasa seri tutorial php dasar ini bermanfaat, silakan bagikan kepada yang lainnya.
Terima kasih banyak!