Bayangkan setiap fungsi sebagai ruangan berdinding kedap suara: variabel yang dibuat di dalamnya tidak terdengar dari luar, dan variabel di luar tidak masuk ke dalamnya. Inilah variable scope — wilayah program tempat sebuah variabel hidup dan bisa diakses. PHP memilih aturan scope yang sederhana: variabel yang didefinisikan di tubuh fungsi bersifat lokal untuk fungsi tersebut, sedangkan variabel di tingkat berkas hidup di scope global, dan keduanya tidak bertukar isi secara otomatis. Pada Chapter ini kita petakan wilayah-wilayah itu beserta jembatan resmi yang menyambungkannya.
Scope Lokal Fungsi #
Setiap pemanggilan fungsi membawa “ruangan” variabelnya sendiri. Variabel yang diberi nilai di dalam fungsi — baik hasil perhitungan maupun variabel sementara — lahir saat barisnya dieksekusi dan lenyap begitu fungsi selesai. Nama yang sama di luar fungsi tidak terganggu, dan sebaliknya.
<?php
$pesan = "pesan dari scope global";
function tampilkanPesanLokal(): void
{
$pesan = "pesan dari scope lokal";
echo $pesan . "\n";
}
tampilkanPesanLokal();
echo $pesan . "\n";Output yang Dihasilkan:
pesan dari scope lokal
pesan dari scope globalPenugasan $pesan di dalam tampilkanPesanLokal() membuat variabel baru di scope lokal — ia tidak menimpa $pesan global, karena keduanya tinggal di wilayah berbeda. Setelah pemanggilan pertama selesai, variabel lokal itu hilang; echo $pesan di baris terakhir membaca variabel global yang tak tersentuh. Pembatasan ini sengaja dijaga: tanpa dinding scope, setiap fungsi bisa merusak data milik fungsi lain hanya dengan kebetulan memakai nama yang sama.
Dinding itu juga berlaku antar-fungsi. Dua fungsi berikut sama-sama memakai nama $tarif tanpa saling mengganggu:
<?php
function hitungPajak(float $harga): float
{
$tarif = 0.11;
return $harga * $tarif;
}
function hitungOngkir(float $berat): float
{
$tarif = 5000;
return $berat * $tarif;
}
echo hitungPajak(1000000) . "\n";
echo hitungOngkir(2) . "\n";Output yang Dihasilkan:
110000
10000$tarif di hitungPajak() bernilai 0.11 dan $tarif di hitungOngkir() bernilai 5000 — dua variabel berbeda yang kebetulan berbagi nama. Hasil 110000 dan 10000 menunjukkan keduanya bekerja independen. Perlu dicatat: jika sebuah fungsi membaca variabel yang tidak pernah diberi nilai di scope-nya, PHP memunculkan Warning: Undefined variable — bukan diam-diam membaca variabel global.
Kata Kunci global #
Lalu bagaimana bila fungsi memang perlu membaca atau memperbarui variabel global? PHP menyediakan kata kunci global yang “mengimpor” variabel global ke scope lokal. Setelah deklarasi global $totalPenjualan;, nama tersebut di dalam fungsi menunjuk ke variabel global yang sama.
<?php
$totalPenjualan = 0;
function catatPenjualan(int $jumlah): void
{
global $totalPenjualan;
$totalPenjualan += $jumlah;
}
catatPenjualan(50000);
catatPenjualan(75000);
echo "Total: Rp$totalPenjualan\n";Output yang Dihasilkan:
Total: Rp125000Kedua pemanggilan menambah 50000 lalu 75000 ke variabel global yang sama, menghasilkan Rp125000. Perhatikan bahwa variabel global tetap perlu dibuat dulu di luar fungsi; global mengimpor nama yang sudah ada, bukan menciptakannya.
Array Superglobal $GLOBALS #
Jembatan kedua menuju scope global adalah array $GLOBALS — superglobal bawaan PHP yang berisi seluruh variabel global, terindeks nama variabelnya. Berbeda dengan global, $GLOBALS bisa diakses tanpa deklarasi apa pun, di scope mana pun, kapan pun.
<?php
$namaAplikasi = "Kelas PHP";
function bacaNamaAplikasi(): string
{
return $GLOBALS["namaAplikasi"];
}
echo bacaNamaAplikasi() . "\n";Output yang Dihasilkan:
Kelas PHPIndeks "namaAplikasi" (tanpa tanda $) merujuk variabel global $namaAplikasi, sehingga fungsi mengembalikan Kelas PHP tanpa deklarasi global. Dalam praktik, $GLOBALS justru lebih jarang dipakai daripada global — kebanyakan kemunculannya ada di kode lama atau kode framework tingkat rendah. Alasannya sama: ketergantungan pada state global membuat alur data sulit dilacak. Gunakan pengetahuan ini untuk membaca kode yang ada, bukan resep untuk menulis yang baru.
Variabel static yang Bertahan #
Variabel lokal biasanya lenyap saat fungsi selesai — tetapi kata kunci static memberinya daya tahan istimewa: nilai variabel bertahan di antara pemanggilan, dan inisialisasinya hanya dijalankan sekali. Setiap pemanggilan berikutnya melanjutkan nilai terakhir.
<?php
function pesananBerikutnya(): int
{
static $nomor = 1000;
return ++$nomor;
}
echo pesananBerikutnya() . "\n";
echo pesananBerikutnya() . "\n";
echo pesananBerikutnya() . "\n";Output yang Dihasilkan:
1001
1002
1003Baris static $nomor = 1000; dieksekusi hanya pada pemanggilan pertama. Pre-increment ++$nomor kemudian menaikkan nilai menjadi 1001, lalu 1002, lalu 1003 — tiga pemanggilan, satu variabel yang terus hidup. Pola counter seperti ini adalah kasus penggunaan static yang paling klasik dan sah; kami bahas pola lainnya (termasuk jebakannya) pada Chapter Global dan Static Variables.
include Berbagi Scope Global #
Ketika satu berkas dijalankan, include dan require menempelkan kode berkas lain ke titik pemanggilan — termasuk scope-nya. Kode yang di-include di tingkat teratas berbagi scope global, sehingga variabel yang didefinisikan berkas include terlihat oleh kode sesudahnya. Dinding scope hanya berdiri di sekeliling fungsi, bukan di sekeliling berkas.
<?php
include 'konfigurasi.php';
function infoAplikasi(): string
{
$nama = $namaAplikasi ?? "(tidak terlihat dari fungsi)";
return "Aplikasi $nama";
}
echo "Di scope global: $namaAplikasi v$versiAplikasi\n";
echo "Di dalam fungsi: " . infoAplikasi() . "\n";Output yang Dihasilkan:
Di scope global: Toko Budi v2.1
Di dalam fungsi: Aplikasi (tidak terlihat dari fungsi)Berkas konfigurasi.php (tersedia di bagian bawah halaman) berisi dua penugasan variabel di tingkat teratas. Setelah include, keduanya menjadi bagian scope global — baris echo pertama membacanya dengan bebas, mencetak Toko Budi v2.1. Sebaliknya, fungsi infoAplikasi() tetap tidak bisa melihat $namaAplikasi; operator ?? menyelamatkan fungsi dari Warning: Undefined variable dengan mengembalikan teks cadangan. Pola “berkas konfigurasi yang di-include” sangat umum di aplikasi PHP — sekarang Anda tahu mengapa variabelnya bisa dibaca di tingkat teratas namun tidak di dalam fungsi.
Sekilas tentang Closure dan use() #
Ada satu pengecualian elegan untuk dinding scope: closure — fungsi anonim yang bisa “menangkap” variabel luar lewat klausa use(). Variabel yang ditangkap ikut tersimpan bersama fungsi walaupun scope asalnya sudah selesai. Kita baru akan membahasnya tuntas pada Chapter Anonymous Functions dan Closures; berikut cuplikan pembukanya.
<?php
$diskon = 0.1;
$hitungHarga = function (float $harga) use ($diskon): float {
return $harga * (1 - $diskon);
};
echo $hitungHarga(200000) . "\n";Output yang Dihasilkan:
180000Klausa use ($diskon) menyalin nilai $diskon dari scope global ke dalam closure pada saat pembuatannya. Ketika $hitungHarga(200000) dipanggil, 200000 dikalikan 0.9 dan hasilnya 180000. Berbeda dengan global, penangkapan use() bersifat lokal untuk fungsi itu saja dan tidak membuka akses ke seluruh scope global — alasan utama closure dianggap jauh lebih bersih untuk membawa data ke dalam fungsi.
Ringkasan #
Scope memisahkan wilayah hidup variabel: lokal di dalam tiap fungsi, global di tingkat berkas, tanpa bocor antar keduanya. Kata kunci global, array $GLOBALS, dan variabel static adalah tiga pintu resmi menembus dinding itu — masing-masing dengan biaya keterbacaan yang perlu ditimbang — sementara include berbagi scope global dan closure menangkap variabel secara terkendali lewat use(). Dengan peta wilayah yang kini lengkap, kita siap menempa fungsi tanpa nama: anonymous functions dan closure pada Chapter berikutnya.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
konfigurasi.php
Unduh berkas<?php
// konfigurasi.php — nilai konfigurasi aplikasi di scope global
$namaAplikasi = "Toko Budi";
$versiAplikasi = "2.1";