Zasięg zmiennych

Zasięg zmiennej jest zależny od miejsca , w jakim została zdefiniowana . Najczęściej zmienne PHP widoczne tylko w pojedynczym zasięgu . Taki zasięg rozciąga się na pliki dołączane funkcjami include( ) i require( ) . Na przykład :

 
$a

 
=

 
1

 
;

 
include

 
"b.inc"

 
;



Tutaj zmienna $a będzie dostępna także w dołączonym pliku b.inc . Jednakże w funkcjach zdefiniowanych przez użytkownika zmienne mają zasięg lokalny . Każda zmienna użyta wewnątrz funkcji jest domyślnie ograniczona do zasięgu lokalnego , np .

 
$a

 
=

 
1

 
;

 
/

 
*

 
zasięg

 
globalny

 
*

 
/

 
function

 
Test(

 
)

 
{

 
echo

 
$a

 
;

 
/

 
*

 
odwołanie

 
do

 
zmiennej

 
o

 
zasięgu

 
lokalnym

 
*

 
/

 
}

 
Test()

 
;



Ten skrypt nie wyświetli niczego , ponieważ instrukcja echo odwołuje się do zmiennej lokalnej $a , której jak dotąd nie została przypisana żadna wartość . Można tu zauważyć różnicę w stosunku do języka C , gdzie zmienne globalne zawsze dostępne wewnątrz definicji funkcji , o ile nie zostały nadpisane przez lokalną definicję zmiennej . Może to spowodować taki problem , że ktoś może nieodwracalnie zmienić wartość zmiennej globalnej . W PHP zmienne globalne muszą być jawnie określone jako globalne wewnątrz funkcji , w której mają być użyte , do czego używamy słowa kluczowego global . Na przykład :

 
$a

 
=

 
1

 
;

 
$b

 
=

 
2

 
;

 
function

 
Sum(

 
)

 
{

 
global

 
$a

 
,

 
$b

 
;

 
$b

 
=

 
$a

 
+

 
$b

 
;

 
}

 
Sum()

 
;

 
echo

 
$b

 
;



Powyższy skrypt wyświetli wynik " 3 " . Przez zadeklarowanie wewnątrz funkcji globalności zmiennych $a i $b , wszystkie odwołania do tych zmiennych będą odnosiły się do ich globalnych wersji . Nie ma żadnych ograniczeń w ilości zmiennych globalnych , na których chcemy operować wewnątrz funkcji .

Drugim sposobem uzyskania dostępu do zmiennych globalnych wewnątrz funkcji jest użycie specjalnej , zdefiniowanej przez PHP tablicy $GLOBALS . Powyższy przykład można zatem przepisać tak :

 
$a

 
=

 
1

 
;

 
$b

 
=

 
2

 
;

 
function

 
Sum(

 
)

 
{

 
$GLOBALS["b"

 
]

 
=

 
$GLOBALS["a"

 
]

 
+

 
$GLOBALS["b"]

 
;

 
}

 
Sum()

 
;

 
echo

 
$b

 
;



$GLOBALS jest tablicą asocjacyjną , gdzie nazwa zmiennej jest kluczem , a zawartość zmiennej wartością komórki tablicy .

Jeszcze jedną ważną rzeczą , związaną z zasięgiem zmiennych jest zmienna statyczna ( ang . static variable ) . Zmienna statyczna może mieć wyłącznie zasięg lokalny , ale nie traci swojej wartości , kiedy program opuści ten zasięg lokalny , w którym dana zmienna statyczna się znajduje . Proszę rozważyć poniższy przykład :

 
function

 
Test

 
(

 
)

 
{

 
$a

 
=

 
0

 
;

 
echo

 
$a

 
;

 
$a++

 
;

 
}



Ta funkcja jest bezużyteczna , gdyż przy każdym jej wywołaniu zmienna $a otrzymuje wartość 0 , w związku z czym funkcja stale wyświetla " 0 " . Występująca potem inkrementacja $a + + nie ma żadnego znaczenia , gdyż funkcja się kończy i zmienna $a Występująca potem inkrementacja $a + + nie ma żadnego znaczenia , gdyż funkcja się kończy i zmienna $a znika . Aby powyższa funkcja miała jakiś sens , należy zapobiec gubieniu wartości $a , do czego używamy słowa kluczowego static :

 
function

 
Test(

 
)

 
{

 
static

 
$a

 
=

 
0

 
;

 
echo

 
$a

 
;

 
$a++

 
;

 
}



Teraz , za każdym wywołaniem funkcji test , zostanie wyświetlona wartość zmiennej $a , po czym ta zmienna zostanie inkrementowana .

Zmienne statyczne pozwalają też na wykorzystanie funkcji rekurencyjnych , czyli takich , które wywołują same siebie . Funkcje rekurencyjne należy pisać ostrożnie , gdyż łatwo jest wywołać nieskończoną rekurencję . Musisz być pewny , że masz odpowiednie mechanizmy do zatrzymania rekurencji w pewnym momencie . Poniższa funkcja rekurencyjnie liczy do 10 , używając zmiennej statycznej $licznik , aby wiedzieć , kiedy ma się zatrzymać :

 
function

 
Test(

 
)

 
{

 
static

 
$licznik

 
=

 
0

 
;

 
$licznik++

 
;

 
echo

 
$licznik

 
;

 
if

 
($licznik

 
10

 
)

 
{

 
Test

 
()

 
;

 
    }

 
$licznik--

 
;

 
}