[Ezt a fejezetet érdemes elolvasnod, még akkor is, ha profi vagy valamilyen programozási nyelvben, mert a PHP tartogat egy-két érdekes meglepetést...]
Egy változó hatásköre az a környezet, amiben a változó definiált. A legtöbb esetben minden PHP változónak egy hatásköre van. Ez az egyetlen hatáskör kiterjed az include és a require segítségével használt file-okra is. Például:
1 2 3 $a = 1; 4 include "b.inc"; 5 6 |
Itt az $a változó elérhető lesz az include-olt b.inc scriptben is. Felhasználói függvényeken belül egy lokális függvényhatáskör lép érvénybe. Minden egyes függvényen belül használt változó csak azon a bizonyos függvényen belülre van korlátozva. Például:
1 2 3 $a = 1; /* globális hatáskör */ 4 5 Function Test () { 6 echo $a; /* egy helyi változót vár */ 7 } 8 9 Test (); 10 11 |
Ez a script nem fog semmilyen kimenetet sem eredményezni, mivel az echo kifejezés az $a változónak egy helyi változatára utal, és ehhez még nem került hozzárendelésre érték abban a hatáskörben. Bizony, bizony, ez egy "kicsit" különbözik a C nyelv filozófiájától, ahol egy globális változó automatikusan elérhető bármely függvényből, feltéve ha a függvényben újra nem definiáltad azt a változót. Ez bizony problémák forrása lehet, ha az ember véletlenül megváltoztat egy globális változót. A PHP-ben a globális változókat global kulcsszóval deklarálni kell a függvényekben, ha szeretnénk őket a függvényben használni. Például:
1 2 3 $a = 1; 4 $b = 2; 5 6 Function Osszead () { 7 global $a, $b; 8 9 $b = $a + $b; 10 } 11 12 Ossszead (); 13 echo $b; 14 15 |
A fenti script kiírja, hogy "3". $a és $b global-ként való deklarálásával minden utalás ezekre a változókra a globális változót fogja érinteni. Nincs megkötés arra, hogy hány globális változó hatáskörét lehet "becsempészni" a függvénybe.
Globális változók elérésének másik módja a PHP által definiált speciális $GLOBALS tömb használata. Az előbbi példát így is meg lehetett volna írni:
1 2 3 $a = 1; 4 $b = 2; 5 6 Function Osszead () { 7 $GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"]; 8 } 9 10 Osszead (); 11 echo $b; 12 13 |
A $GLOBALS tömb egy asszociatív tömb, ahol a globális változó neve a kulcs, és a változó az értéke.
Egy másik fontos tulajdonsága a változók hatáskörének a static (statikus) változó. Egy statikus változó csak lokális hatáskörben él - egy függvényen belül, de két függvényhívás közt nem felejti el az értékét (pontosabban megfogalmazva a változó hatásköréből való kilépés esetén is megmarad az értéke). Figyeld csak:
1 2 3 Function Test () { #ezt nem Function Body-ból fordítottam... 4 $a = 0; 5 echo $a; 6 $a++; 7 } 8 9 |
Ez egy veszettül haszontalan hülye függvény, ami nem csinál mást, mint minden meghívásakor $a-t 0-ra állítja, aztán kiírja a 0-t. Az $a++ meg teljesen felesleges, mert amint vége a függvénynek, az $a változót tároló bitek felveszik a néhai előnevet. Ahhoz, hogy egy értelmes számolást tudjunk végezni, és megmaradjon a számláló értéke, az $a változót statikusnak kell deklarálni:
1 2 3 Function Test () { 4 static $a = 0; 5 echo $a; 6 $a++; 7 } 8 9 |
Most, valahányszor meghívódik a Test() függvény, kiírja $a-t, majd megnöveli eggyel.
A statikus változók biztosítanak egy módot, hogy a rekurzív függvényekkel bánjunk. Rekurzív az a függvény, amely saját magát meghívja [persze jobb esetben illik feltételhez kötni, különben a szótárban nem úgy fog szerepelni, hogy Rekurzió: ld. rekurzió, hanem úgy, hogy Rekurzió = Stack overflow]. Szóval csak óvatosan azokkal a rekurzív függvényekkel, nehogy végtelen rekurzióba kerüljünk. Ezért kell a feltétel, mert az fogja leállítani a rekurziót. A következő függvény rekurzívan elszámol 10-ig a statikus $count változó segítségével. [Ki ne felejtsd a static kulcsszót, mert akkor nagy baj lesz!]:
1 2 3 Function Test () { 4 static $count = 0; 5 6 $count++; 7 echo $count; 8 if ($count < 10) { 9 Test (); 10 } 11 $count--; 12 } 13 14 |