[PILLOLE PHP] Lo scope
Un argomento che può risultare ostico al pricipiante (o che perlomeno può indurlo a commettere degli errori banali o a perdere tempo) é senz’altro lo scope, ovvero l’ambito di validità di una variabile. Nell’esecuzione di uno script infatti una variabile potrebbe avere diversi significati a dipendenza di dove viene dichiarata..
Iniziamo dunque a vedere quali sono i tre possibili scope di una variabile:
- Globale: una variabile si dice globale quando é dichiarata nello script principale (all’interno delle funzioni non avrà nessun valore);
- Locale: si dice locale una variabile dichiarata all’interno di una funzione (all’esterno della funzione non avrà nessun valore);
- Super-globale: le variabili super-globali sono quelle gestite da PHP ($_SESSION, $_SERVER, $_POST, $_GET, $_REQUEST, $_COOKIE, $_ENV, $_FILES, $GLOBALS). L’ambito di validità delle variabili super-globali é totale, cioé sono valide sia all’interno che all’esterno delle funzioni. Inoltre va considerato che anche le costanti hanno un abito di validità super-globale.
Ma facciamo subito degli esempi.
Le variabili globali non sono disponibili in ambito locale
Come abbiamo già detto, le variabili globali non sono disponibili in ambito locale.
Guarda l’esempio spiegato di seguito:
$var = “Hello”; // $var é dichiarata in abito globale function Test() { // alla funzione Test() si richiede si stampare $var // ma siamo all’interno di una funzione // che non ha accesso alle variabili globali echo $var; } // di conseguenza, invocando la funzione Test() // verrà sollevato un errore ($var non é definita) Test();
Le variabili locali non sono disponibili in ambito globale
Analizziamo l’esempio che segue per capire cosa intendiamo quando diciamo che le variabili locali non sono disponibili in ambito globale:
function Test() { //La funzione Test() ha lo scopo di valorizzare la variabile $var $var = "Hello"; } // Invocando la funzione Test(), $var viene valorizzata // ma solo in ambito locale Test(); // dunque tentare di stamparla a video // in ambito globale produrrà un errore // $var non risulta definita echo $var;
Quindi riassumendo possiamo dire che una funzione, per quanto concerne le variabili, é chiusa ermeticamente rispetto al resto del codice.
Le variabili super-globali sono disponibili ovunque
Adesso, andiamo a dare uno sguardo alle variabili super-globali:
define('MIA_COSTANTE', 'Hello'); function Test() { echo MIA_COSTANTE . ': MIA_COSTANTE in ambito locale<br />'; echo $_SERVER['PHP_SELF'] . ': PHP_SELF in ambito locale<br />'; } Test(); echo MIA_COSTANTE . ': MIA_COSTANTE in ambito globale<br />'; echo $_SERVER['PHP_SELF'] . ': PHP_SELF in ambito globale'; //Il risultato sarà // Hello: MIA_COSTANTE in ambito locale //test.php: PHP_SELF in ambito locale //Hello: MIA_COSTANTE in ambito globale //test.php: PHP_SELF in ambito globale
Come far cadere le barriere tra ambito globale ed ambito locale?
E’ possibile fare in modo che una variabile globale sia resa disponibile anche all’interno di una funzione tramite la keyword global; vediamo come:
// $var é dichiarata in ambito globale $var = "Hello"; function Test() { // Nella funzione Test() dichiaro di voler // utilizzare la variabile globale $var global $var; // Ora $var é disponibile e può essere utilizzata $var .= " World"; } Test(); // Verrà stampato "Hello World" echo $var;
E’ possibile ottenere lo stesso risultato utilizzando l’array $GLOBALS, difatti l’array $GLOBALS è una variabile automaticamente disponibile in tutti gli ambiti senza doverla dichiarare globale per accedervi dall’interno di una funzione.
$var = "Hello"; function Test() { $GLOBALS['var'] .= " World"; } Test(); echo $var;
Considera comunque che rompere gli argini tra ambito locale ed ambito globale é un’operazione da evitare finché é possibile.
Perché l’utilizzo di global é da evitare?
Come detto, per quanto possibile, é meglio evitare l’utilizzo delle tecniche appena descritte.
La netta distinzione di ambiti tra il locale e il globale, che al profano può sembrare un’inutile seccatura, ha delle ragioni molto precise.
Le funzioni generalmente rappresentano una parte di codice molto specifica della quale intravvediamo spesso dei possibili riutilizzi.
Dal momento che:
- non sappiamo quando e in che circostanza potrebbe tornarci utile questa funzione;
- nel caso in cui stiamo lavorando in team ad un grande progetto, potrebbe anche accadere che questa funzione venga riutilizzata da qualcun’altro;
è bene che la funzione sia il più robusta possibile. Global inevitabilemente introduce delle ambiguità e potrebbe portare all’interno della funzione dei valori non corretti.
Una funzione invece, di principio, riceve i dati come argomenti e li restituisce attraverso la keyword return. E questo basta per garantirle la robustezza che auspichiamo.
Per concludere vediamo come passare correttamente gli argomenti ad una funzione.
Argomenti, argomenti facoltativi, argomenti arbitrari
Vediamo brevemente e in pratica come passare gli argomenti ad una funzione in tre diversi casi.
SOMMA DI DUE NUMERI
function Somma($a,$b) { return $a + $b; } echo Somma(5,9);
SOMMA DI DUE O TRE NUMERI (argomenti facoltativi)
//il terzo parametro ($c) lo dichiariamo come //uguale a 0. In questo modo se non verrà inserito //nulla avrà valore 0 e non influirà sulla somma //mentre se passeremo anche il terzo argomento //questo andrà a sovrascrivere la variabile $c function Somma($a,$b,$c = 0) { return $a + $b + $c; } echo Somma(6,2); echo Somma(5,9,6);
SOMMA DI X NUMERI (argomenti arbitrari)
function Somma() { $args = func_get_args(); $return = 0; foreach($args as $value) { $return = $return + $value; } return $return; } echo Somma(2,3,4,5,9,0,0,2);
Conclusione
In questo articolo abbiamo visto alcune caratteristiche fondamentali del liguaggio. La logica degli ambiti di validità delle variabili riveste infatti una notevole importanza nello sviluppo di un codice robusto. Spero di aver chiarito questo argomento che, come ho detto all’inizio, risulta spesso essere un punto critico per i principianti.
15 commenti
Trackback e pingback
[...] scope in PHP (Your Inspiration [...]