Apa itu "ruang lingkup variabel"?
Variabel memiliki "ruang lingkup" terbatas, atau "tempat dari mana mereka dapat diakses". Hanya karena Anda $foo = 'bar';
pernah menulis di suatu tempat di aplikasi Anda tidak berarti Anda dapat merujuk $foo
dari mana saja di dalam aplikasi. Variabel $foo
memiliki ruang lingkup tertentu yang valid dan hanya kode dalam lingkup yang sama memiliki akses ke variabel.
Bagaimana ruang lingkup didefinisikan dalam PHP?
Sangat sederhana: PHP memiliki lingkup fungsi . Itulah satu-satunya jenis pemisah lingkup yang ada di PHP. Variabel di dalam suatu fungsi hanya tersedia di dalam fungsi itu. Variabel di luar fungsi tersedia di mana saja di luar fungsi, tetapi tidak di dalam fungsi apa pun. Ini berarti ada satu ruang lingkup khusus dalam PHP: ruang lingkup global . Variabel apa pun yang dinyatakan di luar fungsi apa pun berada dalam lingkup global ini.
Contoh:
<?php
$foo = 'bar';
function myFunc() {
$baz = 42;
}
$foo
berada dalam lingkup global , $baz
berada dalam lingkup lokal di dalamnya myFunc
. Hanya kode di dalam yang myFunc
memiliki akses $baz
. Hanya kode di luar yang myFunc
memiliki akses $foo
. Tidak ada yang memiliki akses ke yang lain:
<?php
$foo = 'bar';
function myFunc() {
$baz = 42;
echo $foo; // doesn't work
echo $baz; // works
}
echo $foo; // works
echo $baz; // doesn't work
Cakupan dan file yang disertakan
Batas file tidak memisahkan ruang lingkup:
a.php
<?php
$foo = 'bar';
b.php
<?php
include 'a.php';
echo $foo; // works!
Aturan yang sama berlaku untuk include
kode d sebagaimana berlaku untuk kode lain: hanya function
ruang lingkup yang terpisah. Untuk tujuan cakupan, Anda mungkin berpikir untuk memasukkan file seperti menyalin dan menempelkan kode:
cph
<?php
function myFunc() {
include 'a.php';
echo $foo; // works
}
myFunc();
echo $foo; // doesn't work!
Dalam contoh di atas, a.php
dimasukkan ke dalam myFunc
, variabel apa pun di dalam a.php
hanya memiliki lingkup fungsi lokal. Hanya karena mereka tampaknya berada dalam lingkup global a.php
tidak berarti mereka berada, itu sebenarnya tergantung pada konteks mana kode dimasukkan / dijalankan.
Bagaimana dengan fungsi di dalam fungsi dan kelas?
Setiap function
deklarasi baru memperkenalkan ruang lingkup baru, sesederhana itu.
(anonim) fungsi di dalam fungsi
function foo() {
$foo = 'bar';
$bar = function () {
// no access to $foo
$baz = 'baz';
};
// no access to $baz
}
kelas
$foo = 'foo';
class Bar {
public function baz() {
// no access to $foo
$baz = 'baz';
}
}
// no access to $baz
Untuk apa ruang lingkup?
Menangani masalah pelingkupan mungkin tampak menjengkelkan, tetapi ruang lingkup variabel terbatas sangat penting untuk menulis aplikasi yang kompleks! Jika setiap variabel yang Anda deklarasikan akan tersedia dari mana saja di dalam aplikasi Anda, Anda akan melangkahi semua variabel Anda tanpa cara nyata untuk melacak apa yang mengubah apa. Hanya ada begitu banyak nama masuk akal yang dapat Anda berikan kepada variabel Anda, Anda mungkin ingin menggunakan variabel " $name
" di lebih dari satu tempat. Jika Anda hanya dapat memiliki nama variabel yang unik ini sekali di aplikasi Anda, Anda harus menggunakan skema penamaan yang sangat rumit untuk memastikan variabel Anda unik dan bahwa Anda tidak mengubah variabel yang salah dari potongan kode yang salah.
Mengamati:
function foo() {
echo $bar;
}
Jika tidak ada ruang lingkup, apa fungsi fungsi di atas? Dari mana datangnya $bar
? Status apa yang dimilikinya? Apakah bahkan diinisialisasi? Apakah Anda harus memeriksa setiap waktu? Ini tidak bisa dipertahankan. Yang membawa kita ke ...
Melintasi batas ruang lingkup
Cara yang benar: meneruskan variabel masuk dan keluar
function foo($bar) {
echo $bar;
return 42;
}
Variabel $bar
secara eksplisit masuk ke lingkup ini sebagai argumen fungsi. Hanya dengan melihat fungsi ini, jelas dari mana nilai itu bekerja. Kemudian secara eksplisit mengembalikan nilai. Penelepon memiliki kepercayaan diri untuk mengetahui variabel apa yang akan berfungsi dengan fungsi dan dari mana nilai pengembaliannya berasal:
$baz = 'baz';
$blarg = foo($baz);
Memperluas lingkup variabel menjadi fungsi anonim
$foo = 'bar';
$baz = function () use ($foo) {
echo $foo;
};
$baz();
Fungsi anonim secara eksplisit termasuk $foo
dari ruang lingkup di sekitarnya. Perhatikan bahwa ini tidak sama dengan ruang lingkup global .
Jalan yang salah: global
Seperti yang dikatakan sebelumnya, ruang lingkup global agak spesial, dan fungsi dapat secara eksplisit mengimpor variabel dari itu:
$foo = 'bar';
function baz() {
global $foo;
echo $foo;
$foo = 'baz';
}
Fungsi ini menggunakan dan memodifikasi variabel global $foo
. Jangan lakukan ini! (Kecuali jika Anda benar-benar benar-benar benar-benar tahu apa yang Anda lakukan, dan bahkan kemudian: jangan!)
Semua penelepon dari fungsi ini melihat ini:
baz(); // outputs "bar"
unset($foo);
baz(); // no output, WTF?!
baz(); // outputs "baz", WTF?!?!!
Tidak ada indikasi bahwa fungsi ini memiliki efek samping , namun tetap berfungsi . Ini sangat mudah menjadi kekacauan yang kusut karena beberapa fungsi terus memodifikasi dan membutuhkan beberapa negara global. Anda ingin fungsi menjadi stateless , hanya bekerja pada inputnya dan mengembalikan output yang ditentukan, namun sering kali Anda memanggilnya.
Anda harus menghindari penggunaan ruang lingkup global dengan cara apa pun sebanyak mungkin; pastinya Anda tidak harus "menarik" variabel dari lingkup global ke lingkup lokal.