Port�e des variables

La port�e d'une variable d�pend du contexte dans lequel la variable est d�finie. Pour la majorit� des variables, la port�e concerne la totalit� d'un script PHP. Mais, lorsque vous d�finissez une fonction, la port�e d'une variable d�finie dans cette fonction est locale � la fonction. Par exemple :

Exemple #1 Les variables sont locales � la fonction

<?php
$a 
1;
include 
'b.inc';
?>

Ici, la variable $a sera accessible dans le script inclus b.inc. Cependant, dans les fonctions d�finies par l'utilisateur, une nouvelle d�finition de cette variable sera donn�e, limit�e � la fonction. Toute variable utilis�e dans une fonction est, par d�finition, locale. Par exemple :

<?php
$a 
1/* port�e globale */

function test()

    echo 
$a/* port�e locale */
}

test();
?>

Le script n'affichera rien � l'�cran car l'instruction echo() utilise la variable locale $a, et celle-ci n'a pas �t� assign�e pr�alablement dans la fonction. Vous pouvez noter que ce concept diff�re un petit peu du langage C dans lequel une variable globale est automatiquement accessible dans les fonctions, � moins d'�tre red�finie localement dans la fonction. Cela peut poser des probl�mes si vous red�finissez des variables globales localement. En PHP, une variable globale doit �tre d�clar�e � l'int�rieur de chaque fonction afin de pouvoir �tre utilis�e dans cette fonction.

Le mot cl� global

Commen�ons par un exemple avec global :

Exemple #2 Exemple avec global

<?php
$a 
1;
$b 2;
function 
somme() {
    global 
$a$b;
    
$b $a $b;
}
somme();
echo 
$b;

Le script ci-dessus va afficher la valeur 3. En d�clarant globales les variables $a et $b locales de la fonction somme(), toutes les r�f�rences � ces variables concerneront les variables globales. Il n'y a aucune limite au nombre de variables globales qui peuvent �tre manipul�es par une fonction.

Une deuxi�me m�thode pour acc�der aux variables globales est d'utiliser le tableau associatif pr�-d�fini $GLOBALS. Le pr�c�dent exemple peut �tre r��crit de la mani�re suivante :

Exemple #3 Les variables globales et $GLOBALS

<?php
$a 
1;
$b 2;
function 
somme() {
    
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}
somme();
echo 
$b;
?>

Le tableau $GLOBALS est un tableau associatif avec le nom des variables globales comme cl� et les valeurs des �l�ments du tableau comme valeur des variables. Notez que $GLOBALS existe dans tous les contextes, car $GLOBALS est un superglobal. Voici un exemple des super globaux :

Exemple #4 Les variables super globales

<?php
function test_global() {

    
// La plupart des variables pr�-d�finies ne sont pas des "superglobales" et
    // requi�rent le mot-cl� 'global' pour �tre disponibles dans une fonction.
    
global $HTTP_POST_VARS;

    echo 
$HTTP_POST_VARS['name'];

    
// Les superglobales sont accessibles dans tous les contextes
    // et ne requi�rent pas 'global'.  Les superglobales sont disponibles
    // depuis PHP 4.1.0 et HTTP_POST_VARS est de plus en plus
    // d�pr�ci�.
    
echo $_POST['name'];
}
?>

Utilisation des variables static

Une autre caract�ristique importante de la port�e des variables est la notion de variable static. Une variable statique a une port�e locale uniquement, mais elle ne perd pas sa valeur lorsque le script appelle la fonction. Prenons l'exemple suivant :

Exemple #5 Les variables statiques

<?php
function test()
{
    
$a 0;
    echo 
$a;
    
$a++;
}
?>

Cette fonction est un peu inutile car � chaque fois qu'elle est appel�e, elle initialise $a0 et affiche "0". L'incr�mentation de la variable ($a++) ne sert pas � grand chose, car d�s que la fonction est termin�e, la variable $a dispara�t. Pour faire une fonction de comptage utile, c'est-�-dire qui ne perdra pas la trace du compteur, la variable $a est d�clar�e comme une variable statique :

Exemple #6 Les variables statiques (2)

<?php
function test()
{
    static 
$a 0;
    echo 
$a;
    
$a++;
}
?>

Maintenant, la variable $a est initialis�e uniquement lors du premi�re appel � la fonction et, � chaque fois que la fonction test() est appel�e, elle affichera une valeur de $a incr�ment�e de 1.

Les variables statiques sont essentielles lorsque vous faites des appels r�cursifs � une fonction. Une fonction r�cursive est une fonction qui s'appelle elle-m�me. Il faut faire attention lorsque vous �crivez une fonction r�cursive car il est facile de faire une boucle infinie. Vous devez v�rifier que vous avez bien une condition qui permet de terminer votre r�cursivit�. La fonction suivante compte r�cursivement jusqu'� 10, en utilisant la variable $count pour savoir quand il faut s'arr�ter :

Exemple #7 Les variables statiques et la r�cursivit�

<?php
function test()
{
    static 
$count 0;

    
$count++;
    echo 
$count;
    if (
$count 10) {
        
test();
    }
    
$count--;
}
?>

Note: Les variables statiques doivent �tre d�clar�es comme dans l'exemple ci-dessus. Tenter d'assigner des valeurs � ces variables qui sont le r�sultat d'expressions causera une erreur d'analyse.

Exemple #8 D�claration de variables statiques

<?php
function foo(){
    static 
$int 0;          // correct
    
static $int 1+2;        // faux  (car c'est une expression)
    
static $int sqrt(121);  // faux  (car c'est aussi une expression)

    
$int++;
    echo 
$int;
}
?>


Les r�f�rences avec les variables global et static

Le Zend Engine 1, sur qui repose PHP 4, impl�mente les options static et global pour les variables, en terme de r�f�rence. Par exemple, une vraie variable globale est import�e dans un contexte de fonction avec global. Cette commande cr�e en fait une r�f�rence sur la variable globale. Cela peut vous mener � des comportements inattendus, par exemple :

<?php
function test_global_ref() {
    global 
$obj;
    
$obj = &new stdclass;
}

function 
test_global_noref() {
    global 
$obj;
    
$obj = new stdclass;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>

L'exemple ci-dessus va afficher :


NULL
object(stdClass)(0) {
}

Un comportement similaire s'applique � la commande static. Les r�f�rences ne sont pas stock�es dynamiquement :

<?php
function &get_instance_ref() {
    static 
$obj;

    echo 
'Objet statique : ';
    
var_dump($obj);
    if (!isset(
$obj)) {
        
// Assigne une r�f�rence � une variable statique
        
$obj = &new stdclass;
    }
    
$obj->property++;
    return 
$obj;
}

function &
get_instance_noref() {
    static 
$obj;

    echo 
'Objet statique : ';
    
var_dump($obj);
    if (!isset(
$obj)) {
        
// Assigne une objet � une variable statique
        
$obj = new stdclass;
    }
    
$obj->property++;
    return 
$obj;
}

$obj1 get_instance_ref();
$still_obj1 get_instance_ref();
echo 
"\n";
$obj2 get_instance_noref();
$still_obj2 get_instance_noref();
?>

L'exemple ci-dessus va afficher :


Objet statique : NULL
Objet statique : NULL

Objet statique : NULL
Objet statique : object(stdClass)(1) {
["property"]=>
int(1)
}

Ces exemples illustrent les probl�mes rencontr�s lors de l'assignation de r�f�rence � des variables statiques, qui sont oubli�es lorsque vous appelez &get_instance_ref() une seconde fois.