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 $foodari mana saja di dalam aplikasi. Variabel $foomemiliki 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;
}
$fooberada dalam lingkup global , $bazberada dalam lingkup lokal di dalamnya myFunc. Hanya kode di dalam yang myFuncmemiliki 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 includekode d sebagaimana berlaku untuk kode lain: hanya functionruang 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.phpdimasukkan ke dalam myFunc, variabel apa pun di dalam a.phphanya memiliki lingkup fungsi lokal. Hanya karena mereka tampaknya berada dalam lingkup global a.phptidak berarti mereka berada, itu sebenarnya tergantung pada konteks mana kode dimasukkan / dijalankan.
Bagaimana dengan fungsi di dalam fungsi dan kelas?
Setiap functiondeklarasi 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 $barsecara 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 $foodari 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.