"Değişken kapsam" nedir?
Değişkenlerin sınırlı bir "kapsamı" veya "erişilebilir oldukları yerler" vardır. Yazdığın Çünkü $foo = 'bar';
bir kere bir yere uygulamanızda size başvurmak anlamına gelmez $foo
gelen her yerde uygulama içinde başka. Değişkenin $foo
geçerli olduğu belirli bir kapsamı vardır ve yalnızca aynı kapsamdaki kodun değişkene erişimi vardır.
PHP'de kapsam nasıl tanımlanır?
Çok basit: PHP fonksiyon kapsamına sahiptir . PHP'de var olan tek kapsam ayırıcısı budur. Bir işlevin içindeki değişkenler yalnızca bu işlevin içinde kullanılabilir. İşlevlerin dışındaki değişkenler işlevlerin dışında herhangi bir yerde bulunur, ancak hiçbir işlevin içinde kullanılamaz. Bu PHP'de özel bir kapsam olduğu anlamına gelir: global kapsam. Herhangi bir işlev dışında bildirilen herhangi bir değişken bu global kapsam dahilindedir.
Misal:
<?php
$foo = 'bar';
function myFunc() {
$baz = 42;
}
$foo
olduğu küresel , kapsam $baz
bir olduğunu yerel kapsamı içine myFunc
. Yalnızca içindeki kodun myFunc
erişimi var $baz
. Yalnızca dışarıdaki kodun myFunc
erişimi var $foo
. İkisinin de diğerine erişimi yok:
<?php
$foo = 'bar';
function myFunc() {
$baz = 42;
echo $foo; // doesn't work
echo $baz; // works
}
echo $foo; // works
echo $baz; // doesn't work
Kapsam ve dahil edilen dosyalar
Dosya sınırları yapmak değil ayrı kapsamını:
a.php
<?php
$foo = 'bar';
b.php
<?php
include 'a.php';
echo $foo; // works!
include
Diğer kodlar için geçerli olan d kodu için aynı kurallar geçerlidir : yalnızca function
ayrı kapsamı. Kapsam amacıyla, kopyalama ve yapıştırma kodu gibi dosyaları dahil etmeyi düşünebilirsiniz:
c.php
<?php
function myFunc() {
include 'a.php';
echo $foo; // works
}
myFunc();
echo $foo; // doesn't work!
Yukarıdaki örnekte, a.php
içine dahil edilmiş, içindeki myFunc
değişkenler a.php
sadece yerel fonksiyon kapsamına sahiptir. Onlar sırf görünür küresel kapsamda olmak a.php
ille oldukları anlamına gelmez, aslında kod dahil olduğunu / idam hangi bağlam bağlıdır.
Fonksiyonlar ve sınıflar içindeki fonksiyonlar ne olacak?
Her yeni function
deklarasyon yeni bir kapsam getiriyor, bu kadar basit.
(anonim) işlevler içindeki işlevler
function foo() {
$foo = 'bar';
$bar = function () {
// no access to $foo
$baz = 'baz';
};
// no access to $baz
}
sınıflar
$foo = 'foo';
class Bar {
public function baz() {
// no access to $foo
$baz = 'baz';
}
}
// no access to $baz
Kapsam ne işe yarar?
Kapsam belirleme sorunlarıyla uğraşmak sinir bozucu görünebilir, ancak karmaşık uygulamalar yazmak için sınırlı değişken kapsam gereklidir! Bildirdiğiniz her değişken, uygulamanızın başka her yerinden kullanılabilirse, neyin değiştiğini izlemek için gerçek bir yol olmadan tüm değişkenlerinize adım atacaksınız. Değişkenlerinize verebileceğiniz çok fazla mantıklı isim var, büyük olasılıkla " $name
" değişkenini birden fazla yerde kullanmak istiyorsunuz . Uygulamanızda bu benzersiz değişken adına yalnızca bir kez sahip olabilirseniz, değişkenlerinizin benzersiz olduğundan ve yanlış değişkeni yanlış kod parçasından değiştirmediğinizden emin olmak için gerçekten karmaşık adlandırma şemalarına başvurmanız gerekir.
Gözlemek:
function foo() {
echo $bar;
}
Kapsam yoksa, yukarıdaki işlev ne yapardı? Nereden $bar
geliyor? Hangi devleti var? Başlatılmış mı? Her seferinde kontrol etmek zorunda mısın? Bu sürdürülemez. Bu da bizi ...
Kapsam sınırlarını aşma
Doğru yol: değişkenleri içeri ve dışarı aktarmak
function foo($bar) {
echo $bar;
return 42;
}
Değişken $bar
, işlev bağımsız değişkeni olarak açıkça bu kapsama giriyor. Sadece bu fonksiyona bakıldığında, çalıştığı değerlerin nereden kaynaklandığı açıktır. Daha sonra açıkça bir değer döndürür . Arayan, işlevin hangi değişkenlerle çalışacağını ve dönüş değerlerinin nereden geldiğini bilme güvenine sahiptir:
$baz = 'baz';
$blarg = foo($baz);
Değişkenlerin kapsamını anonim işlevlere genişletme
$foo = 'bar';
$baz = function () use ($foo) {
echo $foo;
};
$baz();
Anonim işlev $foo
, etrafındaki kapsamı açıkça içerir . Bunun global kapsamla aynı olmadığını unutmayın .
Yanlış yol: global
Daha önce de belirtildiği gibi, küresel kapsam biraz özeldir ve işlevler açıkça değişkenleri buradan alabilir:
$foo = 'bar';
function baz() {
global $foo;
echo $foo;
$foo = 'baz';
}
Bu işlev genel değişkeni kullanır ve değiştirir $foo
. Bunu yapma! (Gerçekten ne yaptığınızı gerçekten bilmiyorsanız ve o zaman bile: Yapmayın!)
Bu işlevin tüm arayanı şudur:
baz(); // outputs "bar"
unset($foo);
baz(); // no output, WTF?!
baz(); // outputs "baz", WTF?!?!!
Bu işlevin herhangi bir yan etkisi olduğuna dair hiçbir belirti yoktur , ancak vardır. Bazı işlevler bazı küresel durumları değiştirmeye ve gerektirmeye devam ettiğinden bu çok kolay bir karışıklık haline gelir . İşlevlerin vatansız olmasını , yalnızca girdilerine göre hareket etmesini ve tanımlanmış çıktıyı döndürmesini istiyorsunuz, ancak birçok kez çağırıyorsunuz.
Global kapsamı mümkün olduğunca herhangi bir şekilde kullanmaktan kaçınmalısınız; şüphesiz değişkenleri küresel kapsamdan yerel bir kapsama “çekmemelisiniz”.