Variabelomfång
Här är den översatta texten på svenska:
```mediawiki
Variabelscope
En variabels scope är den kontext inom vilken den är definierad. För det mesta har alla PHP-variabler bara ett enda scope. Detta enda scope sträcker sig över inkluderade och krävs-filer också. Till exempel:
<?php $a = 1; include 'b.inc'; ?>
Här kommer variabeln $a vara tillgänglig inom den inkluderade b.inc-skripten. Däremot introduceras ett lokalt funktionsscope inom användardefinierade funktioner. Alla variabler som används inom en funktion är som standard begränsade till det lokala funktionsscopet. Till exempel:
<?php $a = 1; /* globalt scope */ function test() { echo $a; /* referens till lokal scope-variabel */ } test(); ?>
Detta skript kommer att generera en undefined variable E_WARNING (eller en E_NOTICE före PHP 8.0.0) diagnostik. Om inställningen display_errors i INI är satt för att dölja sådana diagnostikmeddelanden kommer inget att visas. Detta beror på att echo-satsen refererar till en lokal version av variabeln $a, och den har inte tilldelats ett värde inom detta scope. Du kanske märker att detta är lite annorlunda från C-språket där globala variabler i C automatiskt är tillgängliga för funktioner om de inte specifikt skrivs över av en lokal definition. Detta kan orsaka vissa problem eftersom personer av misstag kan ändra en global variabel. I PHP måste globala variabler deklareras som globala inom en funktion om de ska användas i den funktionen.
Nyckelordet global
Först, ett exempel på användning av global:
Exempel #1 Använda global
<?php $a = 1; $b = 2; function Sum() { global $a, $b; $b = $a + $b; } Sum(); echo $b; ?>
Ovanstående skript kommer att ge 3 som utmatning. Genom att deklarera $a och $b som globala inom funktionen, kommer alla referenser till dessa variabler att referera till den globala versionen. Det finns ingen begränsning för hur många globala variabler som kan manipuleras av en funktion.
Ett andra sätt att komma åt variabler från det globala scopet är att använda den speciella PHP-definierade $GLOBALS-arrayen. Det tidigare exemplet kan skrivas om som:
Exempel #2 Använda $GLOBALS istället för global
<?php $a = 1; $b = 2; function Sum() { $GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b']; } Sum(); echo $b; ?>
$GLOBALS-arrayen är en associativ array där namnet på den globala variabeln är nyckeln och innehållet i den variabeln är värdet på arrayelementet. Notera att $GLOBALS existerar i vilket scope som helst, detta eftersom $GLOBALS är en superglobal. Här är ett exempel som demonstrerar kraften hos superglobaler:
Exempel #3 Exempel som demonstrerar superglobaler och scope
<?php function test_superglobal() { echo $_POST['name']; } ?>
Notera:
Att använda global-nyckelordet utanför en funktion är inte ett fel. Det kan användas om filen är inkluderad från insidan av en funktion.
Använda statiska variabler
En annan viktig funktion för variabelscoping är den statiska variabeln. En statisk variabel existerar endast i ett lokalt funktionsscope, men den förlorar inte sitt värde när programutförandet lämnar detta scope. Överväg följande exempel:
Exempel #4 Exempel som demonstrerar behovet av statiska variabler
<?php function test() { $a = 0; echo $a; $a++; } ?>
Denna funktion är ganska meningslös eftersom varje gång den anropas sätts $a till 0 och skriver ut 0. $a++ som inkrementerar variabeln tjänar inget syfte eftersom så snart funktionen avslutas försvinner variabeln $a. För att skapa en användbar räknarfunktion som inte tappar spår av den nuvarande räkningen, deklareras variabeln $a som statisk:
Exempel #5 Exempel på användning av statiska variabler
<?php function test() { static $a = 0; echo $a; $a++; } ?>
Nu initieras $a endast vid första anropet av funktionen och varje gång test()-funktionen anropas kommer den att skriva ut värdet av $a och öka det.
Statiska variabler ger också ett sätt att hantera rekursiva funktioner. En rekursiv funktion är en som anropar sig själv. Det måste tas försiktighet vid skrivning av en rekursiv funktion eftersom det är möjligt att göra den rekursiv på obestämd tid. Du måste se till att du har ett adekvat sätt att avsluta rekursionen. Följande enkla funktion räknar rekursivt till 10, med den statiska variabeln $count för att veta när den ska sluta:
Exempel #6 Statiska variabler med rekursiva funktioner
<?php function test() { static $count = 0; $count++; echo $count; if ($count < 10) { test(); } $count--; } ?>
Statiska variabler kan tilldelas värden som är resultatet av konstanta uttryck, men dynamiska uttryck, såsom funktionsanrop, kommer att orsaka ett tolkningsfel.
Exempel #7 Deklarera statiska variabler
<?php function foo(){ static $int = 0; // korrekt static $int = 1+2; // korrekt static $int = sqrt(121); // fel (eftersom det är en funktion) $int++; echo $int; } ?>
Från och med PHP 8.1.0, när en metod som använder statiska variabler ärvs (men inte skrivs över), kommer den ärvda metoden nu att dela statiska variabler med föräldrametoden. Detta innebär att statiska variabler i metoder nu beter sig på samma sätt som statiska egenskaper.
Exempel #8 Användning av statiska variabler i ärvda metoder
<?php class Foo { public static function counter() { static $counter = 0; $counter++; return $counter; } } class Bar extends Foo {} var_dump(Foo::counter()); // int(1) var_dump(Foo::counter()); // int(2) var_dump(Bar::counter()); // int(3), före PHP 8.1.0 int(1) var_dump(Bar::counter()); // int(4), före PHP 8.1.0 int(2) ?>
Notera:
Statiska deklarationer löses under kompileringstid.
Referenser med globala och statiska variabler
PHP implementerar den statiska och globala modifikatorn för variabler i termer av referenser. Till exempel, en verkligt global variabel som importeras inom ett funktionsscope med global-uttalandet skapar faktiskt en referens till den globala variabeln. Detta kan leda till oväntat beteende vilket det följande exemplet tar upp:
<?php function test_global_ref() { global $obj; $new = new stdClass; $obj = &$new; } function test_global_noref() { global $obj; $new = new stdClass; $obj = $new; } test_global_ref(); var_dump($obj); test_global_noref(); var_dump($obj); ?>
Ovanstående exempel kommer att generera:
NULL object(stdClass)#1 (0) { }
En liknande beteende gäller för det statiska uttalandet. Referenser lagras inte statiskt:
<?php function &get_instance_ref() { static $obj; echo 'Statisk objekt: '; var_dump($obj); if (!isset($obj)) { $new = new stdClass; // Tilldela en referens till den statiska variabeln $obj = &$new; } if (!isset($obj->property)) { $obj->property = 1; } else { $obj->property++; } return $obj; } function &get_instance_noref() { static $obj; echo 'Statisk objekt: '; var_dump($obj); if (!isset($obj)) { $new = new stdClass; // Tilldela objektet till den statiska variabeln $obj = $new; } if (!isset($obj->property)) { $obj->property = 1; } else { $obj->property++; } return $obj; } $obj1 = get_instance_ref(); $still_obj1 = get_instance_ref(); echo "\n"; $obj2 = get_instance_noref(); $still_obj2 = get_instance_noref(); ?>
Ovanstående exempel kommer att generera:
Statisk objekt: NULL Statisk objekt: NULL Statisk objekt: NULL Statisk objekt: object(stdClass)#3 (1) { ["property"]=> int(1) }
Detta exempel demonstrerar att när man tilldelar en referens till en statisk variabel, så kommer den inte ihåg när du anropar &get_instance_ref()-funktionen en andra gång.
Sidslut
Orginalhemsidan på Engelska : https://www.php.net/manual/en/language.variables.scope.php
PHP
Språkreferens
Språkreferens#Variabler
Det här är en maskinöversättning av PHP-manualen till svenska. Om du hittar fel är vi tacksamma om du rapporterar dem via formuläret som finns på https://www.linux.se/kontaka-linux-se/