Setiap fungsi PHP memiliki lingkup variabelnya sendiri, yaitu wilayah tempat sebuah nama variabel berlaku. Topik ini membahas lingkup lokal pada tubuh fungsi, variabel static yang nilainya bertahan antar pemanggilan, serta kata kunci global beserta jebakannya. Setelah topik ini dibaca, batas hidup sebuah variabel dapat dipastikan, dan aliran data antara fungsi dengan lingkup luar dapat diatur secara eksplisit.
Lingkup lokal fungsi#
Variabel yang dideklarasikan di dalam tubuh fungsi bersifat lokal, yaitu diciptakan saat fungsi dipanggil dan hilang saat fungsinya selesai. Variabel di luar fungsi juga tidak terlihat dari dalam fungsi, sehingga dua nama yang sama pada dua lingkup berbeda merujuk dua penyimpanan yang terpisah. Parameter berperilaku sama, karena parameter pada dasarnya adalah variabel lokal yang nilainya diisi dari argumen pemanggilan.
Aturan ini membuat fungsi menjadi unit yang mandiri. Hasil pemanggilan tidak bergantung pada variabel apa pun di luar deklarasinya, dan pemanggilan yang berulang selalu dimulai dari keadaan yang bersih. Kode yang bergantung pada perilaku ini lebih mudah diuji karena masukannya eksplisit lewat parameter dan keluarannya eksplisit lewat nilai kembalian.
Skrip berikut membandingkan dua lingkup yang memuat nama $total yang sama. Di dalam fungsi, $total adalah variabel lokal baru yang selalu dimulai dari nol, sedangkan $total di luar tetap bernilai 100 setelah dua pemanggilan.
<?php
declare(strict_types=1);
$total = 100;
function tambahPoin(int $poin): int
{
$total = 0; // variabel lokal baru, terpisah dari $total di luar
$total += $poin;
return $total;
}
echo tambahPoin(25), "\n";
echo tambahPoin(30), "\n";
echo $total, "\n";25
30
100Nilai 100 pada baris keluaran terakhir membuktikan bahwa dua variabel bernama $total tersebut benar-benar terpisah dan tidak saling memengaruhi. Apabila fungsi memang dimaksudkan mengubah $total milik lingkup luar, hasil perhitungannya dikembalikan dengan return lalu disimpan ke variabel di titik pemanggilan, sehingga perubahan nilai terlihat.
Variabel static#
Variabel lokal yang diawali kata kunci static mempertahankan nilainya antar pemanggilan. Inisialisasinya dijalankan sekali, yaitu pada pemanggilan pertama, sedangkan pemanggilan berikutnya melanjutkan dari nilai terakhir yang tersimpan. Variabel semacam ini tetap tersembunyi dari luar karena lingkupnya tetap lokal, sehingga keadaan yang disimpan hanya dapat dilihat oleh fungsi itu sendiri.
Penggunaan yang lazim adalah penghitung panggilan, cache hasil perhitungan sederhana, dan penanda proses yang hanya boleh berjalan sekali. Setiap fungsi memiliki variabel static-nya sendiri, sehingga dua fungsi yang menggunakan nama variabel yang sama tidak saling bertukar nilai.
Skrip berikut memuat dua fungsi penghitung dengan variabel static bernama sama. Angka pada fungsi pertama berlanjut dari satu ke tiga, sedangkan fungsi kedua memulai dari seratus dan melanjutkannya secara terpisah.
<?php
declare(strict_types=1);
function berikutnya(): int
{
static $nomor = 0;
$nomor++;
return $nomor;
}
function berikutnyaKedua(): int
{
static $nomor = 100;
$nomor++;
return $nomor;
}
echo berikutnya(), "\n";
echo berikutnya(), "\n";
echo berikutnya(), "\n";
echo berikutnyaKedua(), "\n";1
2
3
101Angka 101 pada baris terakhir menunjukkan bahwa $nomor milik berikutnyaKedua() tidak terpengaruh oleh tiga pemanggilan berikutnya(), karena setiap fungsi menyimpan variabel static-nya secara terpisah. Inisialisasinya ditulis sebagai ekspresi konstan, misalnya angka atau string literal, dan baris itu baru dieksekusi pada pemanggilan pertama.
Kata kunci global dan jebakannya#
Kata kunci global menghubungkan fungsi dengan variabel lingkup luar tanpa menyalin nilainya. Pernyataan global $stok; membuat nama $stok di dalam fungsi merujuk pada variabel global yang sama, sehingga pengubahan di dalam fungsi langsung terlihat di luar. Perilaku ini menjadikan global pemicu masalah, bukan sekadar fitur yang jarang digunakan.
Masalah utamanya adalah ketergantungan tersembunyi. Tanda tangan fungsi yang menggunakan global tidak menyebutkan data mana yang dibaca dan diubah, sehingga pembaca harus menelusuri tubuh fungsi untuk mengetahuinya. Pengujian pun menjadi lebih sulit karena variabel global harus disiapkan terlebih dahulu. Satu fungsi yang mengubah variabel global juga mengikat seluruh program pada nama variabel tersebut, karena penggantian nama berarti mengubah perilaku fungsi yang letaknya jauh dari titik pemanggilan.
Alternatifnya adalah melewatkan data melalui parameter dan mengembalikan hasilnya melalui nilai kembalian, sehingga aliran data terbaca dari tanda tangan fungsi. Skrip berikut menggunakan kedua cara pada satu program agar perbedaannya terlihat pada keluaran yang sama.
<?php
declare(strict_types=1);
$stok = 40;
function pinjam(int $jumlah): void
{
global $stok;
$stok -= $jumlah;
}
function pinjamDenganParameter(int $stok, int $jumlah): int
{
return $stok - $jumlah;
}
pinjam(5);
echo 'Lewat global: ', $stok, "\n";
$stok = pinjamDenganParameter($stok, 3);
echo 'Lewat parameter: ', $stok, "\n";Lewat global: 35
Lewat parameter: 32Kesalahan umum#
- Mengharapkan variabel luar terlihat di dalam fungsi. PHP tidak menghubungkan dua lingkup secara otomatis, sehingga membaca variabel luar tanpa
globalmenghasilkan variabel lokal bernilainulldan memicu peringatan. Pesan peringatannya menyebut nama variabel yang tidak terdefinisi, sehingga penyebabnya cepat ditemukan. Perbaikannya dengan meneruskan nilai lewat parameter. - Menganggap inisialisasi
staticdijalankan setiap pemanggilan. Barisstatic $nomor = 0;hanya dieksekusi sekali pada pemanggilan pertama, sehingga penghitungnya tidak kembali ke nilai awal pada pemanggilan berikutnya. Gunakan parameter atau kondisi eksplisit apabila pengaturan ulang memang dikehendaki. - Menyembunyikan perubahan penting di balik
global. Fungsi yang mengubah keadaan global menimbulkan efek samping yang tidak terlihat dari titik panggil. Deklarasikan perubahan tersebut pada tanda tangan fungsi, misalnya menerima keadaan saat ini dan mengembalikan keadaan barunya. - Membaca variabel superglobal langsung di dalam fungsi. Variabel
$_GETdan$_POSTmemang terlihat dari dalam fungsi, tetapi fungsi yang membacanya secara langsung menjadi sulit diuji dan bergantung pada bentuk permintaan HTTP. Ambil nilainya di titik masuk, lalu teruskan ke fungsi sebagai parameter biasa.
Ringkasan#
- Variabel di dalam fungsi bersifat lokal dan terpisah dari variabel bernama sama di luar, sehingga setiap pemanggilan dimulai dari keadaan bersih.
- Variabel lokal
staticdipertahankan antar pemanggilan, diinisialisasi sekali, dan tetap tersembunyi dari lingkup luar. globalmenghubungkan nama lokal dengan variabel global yang sama sehingga perubahan langsung terlihat di luar, tetapi menyembunyikan ketergantungan dari tanda tangan fungsi.- Jalur data yang bersih adalah parameter untuk masukan dan nilai kembalian untuk keluaran, sedangkan superglobal merupakan pengecualian yang terlihat dari lingkup mana pun.
Referensi#
- Lingkup variabel — Manual PHP
— Menetapkan aturan lingkup lokal,
global, dan variabelstaticdi PHP. - Dasar-dasar variabel — Manual PHP — Menjelaskan cara variabel dideklarasikan dan aturan penamaannya.