sobota, 5 października 2019

Global & $GLOBALS

global (słowo kluczowe)


    Słowo kluczowe global służy do intencji odwołania się do zmiennych z głównego scope'a we wnętrzu jakiejś funkcji.

$a = 100;
function separateScope() {
    return $a;
}
separateScope();

W tym przypadku dostaniemy NOTICE ponieważ zmienna $a nie występuje w tym zakresie. 
Aby $a (istnieje w main scope) była w zasięgu (otrzymać referencje) należy dodać deklarację global $a; wewnątrz funkcji. 
W przypadku gdy w głównym zakresie nie istnieje zmienna $a w naszej funkcji (ale i tak wskażemy że chcemy korzystać z $a z zakresu globalnego) do tej zmiennej przypisana zostanie wartość NULL.
Możemy także tworzyć nowe zmienne globalne w wewnętrznych zakresach funkcji, oto przykład:

function separateScope() {
   global $a;
   $a = [1,2,3];
}

separateScope();
array_push($a, 'element added in global scope');

function anotherScope() {
    global $a;
    return $a;
}

print_r(anotherScope());

// Array
// (
//     [0] => 1
//     [1] => 2
//     [2] => 3
//     [3] => element added in global scope
// )

Co istotnie, odniesienie się wewnątrz funkcji do zmiennej za pomocą słowa kluczowego global, oznacza odwołanie do głównego zakresu, a nie do zakresu 'powyżej'. Rozpatrzmy kolejny przykład:

function separatedScope() {
    $a = 100;
    function innerScope() {
        global $a;
        var_dump($a);die; // NULL
    }
    
    innerScope();
}

separatedScope();

Aby powyższy przykład 'zadziałał' należy tuż przed linią $a = 100; dodać odwołanie global $a; co spowoduje utworzenie w głównym zakresie zmiennej $a tym samym sprawiając, że var_dump() wypiszę na ekranie (int) 100.

W przypadku dołączenia pliku ze zmienną globalną za pomocą słowa kluczowego include, funkcja separatedScope() będzie miała w zasięgu zmienną globalną $a.



// otherFile.php -------------------------------------------- 

$a = 100;

// index.php     --------------------------------------------
include 'otherFile.php';

function separatedScope() {
global $a;
var_dump($a);die; // (int) 100
}

separatedScope();



$GLOBALS (tablica superglobalna)


     Kiedy utworzymy zmienną $a w głównym zakresie trafi ona do tablicy superglobalnej $GLOBALS gdzie dla wartości zmiennej będzie klucz 'a'.  Jako, że zmienne globalne można tworzyć także poprzez deklarację w funkcjach global $newVariable; - do tablicy $GLOBALS możemy dodawać elementy z zakresów innych funkcji.

$a = 1;
function separatedScope() {
    global $b;
    $b = 2;
}
separatedScope();

print_r($GLOBALS);

// Array
// (
//     [_GET] => Array()
//     [_POST] => Array()
//     [_COOKIE] => Array()
//     [_FILES] => Array()
//     [GLOBALS] => Array
//  *RECURSION*
//     [a] => 1
//     [b] => 2
// )

W $GLOBALS oprócz naszych zmiennych globalnych znajdują się jeszcze tablice _GET, _POST, _COOKIE, _FILES, i rekurencyjnie zamknięte to samo pod kluczem GLOBALS, dlatego do klucza 'b' możemy odwołać się np tak:

  • $GLOBALS['b']
  • $GLOBALS['GLOBALS']['b']
  • $GLOBALS['GLOBALS']['GLOBALS']['GLOBALS']['b'] 
Dzieje się tak ponieważ: 
$GLOBALS - References all variables available in global scope. An associative array containing references to all variables which are currently defined in the global scope of the script. The variable names are the keys of the array 

A tym samym mamy dostępne $GLOBALS samo w sobie co prowadzi do rekurencji.


Od PHP 5.4 $GLOBALS jest inicjowane tylko wtedy kiedy z niego korzystamy (just-in-time) jest to kolejny argument za tym by nie korzystać z tej tablicy.  


Dość ciekawe zachowanie:


$myGlobals = $GLOBALS;
$myGlobals['test'] = 100

Od tej pory $GLOBALS także będzie posiadał klucz test z wartością 100, pomimo że nie przypisaliśmy superglobalnej tablicy przez referencje do $myGlobals.

Źródła:



Brak komentarzy:

Prześlij komentarz