COURS PHP

  Dernière mise à jour effectuée le : Dimanche 10 août 2003    

Accueil | Eléments de base du langage : La portée des variables

La portée des variables



Introduction

La "portée" d'une variable représente sa capacité à être vue et utilisée par des fonctions ou à l'extérieur des fonctions. Est-elle accessible de partout et pour tout le monde ou bien seulement à l'intérieur d'une fonction ou hors de toute fonction ?

Nous avons déjà vu dans la leçon sur les variables que nous pouvons utiliser des variables sans avoir à les déclarer (sauf celles du type array et object). Le simple fait d'écrire leur nom ou de les utiliser suffit pour que l'interpréteur PHP les prennent en compte et leur attribue le bon type (en fonction de leur contenu).

En fait une variable, peut être déclarée (ou simplement utilisée pour la première fois), soit à l'intérieur d'une fonction, soit en dehors de toute fonction (comme je préconise de faire). Il y a une grande différence entre les deux.

En fait, il existe deux grands univers en PHP. Ce qui se passe à l'extérieur des fonctions, et ce qui se passe à l'intérieur des fonctions.

La maîtrise de ces phénomènes est indispensable pour réussir vos programmes PHP.

 



Les variables locales

Si une variable est déclarée (ou simplement utilisée pour la première fois) à l'intérieur d'une fonction, elle est dite de "portée locale". C'est à dire que cette variable ne sera visible et utilisable qu'à l'intérieur de cette fonction. Pas à l'extérieur.

Prenons un exemple :

<?php

function AffichePrenom() { // début de la fonction AffichePrenom
$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable
echo "La variable contient la valeur $MonPrenom" ; // affiche le contenu de la variable
} // fin de la fonction AffichePrenom

AffichePrenom() ; // appel de la fonction AffichePrenom

?>

Dans cet exemple, la variable $MonPrenom est "déclarée" en l'utilisant pour la première fois à l'intérieur de la fonction AffichePrenom(). C'est à dire entre les accolades "{" et "}" qui définissent la limite d'influence de la fonction (son début et sa fin). L'instruction"echo" qui dit d'écrire quelque chose à l'écran, est aussi à l'intérieur de la fonction. C'est donc la fonction elle même qui affiche ce qui est à l'intérieur de sa zone d'influence.
Quand on appelle cette fonction, rien qu'en écrivant l'instruction :
AffichePrenom() ; // appel de la fonction AffichePrenom
elle se met en oeuvre et fait ce pour quoi elle est faite, et affiche effectivement à l'écran la chaîne de caractères :

"La variable contient la valeur Philippe"

Pour vous en convaincre, cliquez ICI pour faire tourner ce programme et voir le résulta t.

Maintenant, prenons le programme suivant :

<?php

function AffichePrenom() { // début de la fonction AffichePrenom
$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable
} // fin de la fonction AffichePrenom

echo "La variable contient la valeur $MonPrenom" ; // affiche le contenu de la variable

?>

Vous avez remarqué que nous avons sorti l'instruction d'affichage à l'écran de l'intérieur de la fonction, pour la mettre à l'extérieur de la fonction, directement dans le programme, en dehors de toute zone d'influence de cette fonction. Lors de l'exécution de ce programme, le résultat à l'écran est seulement :

"La variable contient la valeur"

Sans plus ! Pour vous en convaincre, cliquez ICI pour faire tourner cet autre programme et voir le résultat.

Tout ceci parce que la variable $MonPrenom est déclarée ou utilisée pour la première fois à l'intérieur d'une fonction. Ceci fait que SEULE cette fonction, et aucune autre, ni même le programme lui même, en dehors de cette fonction n'est plus capable de "voir" la valeur de cette variable. On dit que la variable est purement "locale".
Par ailleurs, une fois l'exécution de la fonction terminée, l'emplacement mémoire de cette variable (le petit casier) est libéré et n'existe même plus. Il sera créé de nouveau lors d'une autre exécution de cette fonction et ce, juste pour le temps de son exécution. A la fin, elle disparaîtra et ainsi de suite.

 



Les variables globales

Normalement, "global", veut dire de partout et pour tout le monde. Oui. Mais... Parce qu'il y a un "mais". Et nous allons voir lequel.

Si vous déclarez vos variables hors de toute fonction, comme je le préconise, ces variables et leur contenu (surtout leur contenu, c'est ce qui nous intéresse), sont accessible de partout. Même à l'intérieur d'une fonction. A une condition (et de taille) : c'est qu'il faut déclarer cette variable comme étant accessible en "global" à l'intérieur de la fonction où vous voulez l'utiliser. Si vous oubliez de déclarer que telle ou telle variable déclarée en dehors de toute fonction, doit être accessible à l'intérieur d'une fonction particulière, cette fonction ne pourra pas voir votre variable. C'est là la cause majeure de bon nombre d'erreurs de programmation.
Prenons quelques exemples pour mieux comprendre comment ça marche :

<?php

$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable

function AffichePrenom() { // début de la fonction AffichePrenom
echo "La variable contient la valeur $MonPrenom" ; // affiche le contenu de la variable

} // fin de la fonction AffichePrenom

AffichePrenom() ; // appel de la fonction AffichePrenom

?>

Ce programme affichera à l'écran, juste la chaîne de caractères :

"La variable contient la valeur"

Sans plus. Cliquez ICI pour faire tourner ce petit programme et vous en convaincre. Pourquoi ? Hé bien parce que la variable ne fait pas partie de l'univers de la fonction (elle a été déclarée en dehors de celle-ci) et qu'en plus on n'a même pas dit à la fonction qu'elle devait accéder à cette variable par le mot magique "global". Pour que ça marche, il faut transformer notre programme de la manière suivante :

<?php

$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable

function AffichePrenom() { // début de la fonction AffichePrenom
global $MonPrenom ; // déclaration de la variable en accès global pour cette fonction
echo "La variable contient la valeur $MonPrenom" ; // affiche le contenu de la variable

} // fin de la fonction AffichePrenom

AffichePrenom() ; // appel de la fonction AffichePrenom

?>

Cette fois, ça va marcher. Cliquez ICI pour faire tourner ce petit programme et vous en convaincre.

Conseil : déclarez vos variables en dehors de toute fonction (zone des variables) et n'oubliez JAMAIS de dire à l'intérieur d'une fonction qu'elle doit pouvoir accéder à telle ou telle variable pour pouvoir s'en servir à l'aide du petit mot magique "global".
De cette manière, vos variables seront visibles non seulement dans les fonction à l'intérieur desquelles vous voulez les utiliser, mais encore elles seront utilisables en dehors de toutes fonction dans le cours de votre programme.

Remarquez la syntaxe de cette déclaration globale : le mot "global" suivi d'un espace, suivi du nom de la variable, sans oublier le ";" (point virgule) qui termine l'instruction.

Bien entendu, une fois rendue accessible à l'intérieur de la fonction par le petit mot magique "global", la variable $MonPrenom est devenue modifiable à l'intérieur comme à l'extérieur de la fonction.
Ce qui veut dire que si l'on modifie la valeur de cette variable à l'intérieur de la fonction, alors, la variable $MonPrenom prend cette nouvelle valeur aussi bien à l'intérieur qu'à l'extérieur de la fonction. Cette nouvelle valeur "écrase" l'ancienne, positionnée lors de la déclaration de la variable en dehors de la fonction. Cette ancienne valeur est définitivement perdue pour tout le monde. Dedans comme dehors.
Là encore, prenons un exemple : soit notre programme modifié de la manière suivante :

<?php

$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable à l'extérieur de la fonction

function AffichePrenom() { // début de la fonction AffichePrenom
global $MonPrenom ; // déclaration de la variable en accès global pour cette fonction
$MonPrenom = "François" ; // modification du contenu de la variable à l'intérieur de la fonction
echo "A l'intérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'intérieur de la fonction

} // fin de la fonction AffichePrenom

AffichePrenom() ; // appel de la fonction AffichePrenom
echo "A l'extérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'extérieur de la fonction

?>

Pour vous en convaincre, cliquez ICI pour faire tourner ce petit programme.

Vu ? Bon ! Alors maintenant, supposons que nous n'ayons pas déclaré la variable en accès global à l'intérieur de la fonction. Juste en supprimant l'instruction correspondante dans la fonction. Notre petit programme deviendrait alors :

<?php

$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable à l'extérieur de la fonction

function AffichePrenom() { // début de la fonction AffichePrenom
$MonPrenom = "François" ; // modification du contenu de la variable à l'intérieur de la fonction
echo "A l'intérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'intérieur de la fonction

} // fin de la fonction AffichePrenom

AffichePrenom() ; // appel de la fonction AffichePrenom
echo "A l'extérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'extérieur de la fonction

?>

Cliquez ICI pour voir ce que ça donne.

Vous voyez ? La variable a deux valeurs différentes : l'une à l'intérieur de la fonction et l'autre à l'extérieur de la fonction.
A l'intérieur, elle a prit la nouvelle valeur "François", et à l'extérieur de la fonction, elle est restée à "Philippe", comme avant, inchangée.
D'où l'importance de bien gérer ses variables et de savoir quand et comment on les rend accessibles en global ou pas.

Remarque : si vous ne déclarez pas votre variable à l'extérieur de toute fonction (zone de déclaration des variables) mais seulement en "global" à l'intérieur d'une fonction, cette variable et sa valeur seront accessible aussi bien à l'intérieur de votre fonction qu'à l'extérieur de celle-ci.
Par contre, il vous faudra donner une valeur initiale à votre variable par une instruction supplémentaire, à l'intérieur de votre fonction, car l'instruction de déclaration en "global" n'autorise pas l'initialisation à une valeur pour une variable dans la même instruction.
J'ai essayé, ça renvoie un tas d'insultes...

 

 



Les variables "static"

Il existe encore un autre mode de gestion des variables à l'intérieur d'une fonction. C'est ce que l'on appelle le mode "static".
D'ordinaire, que la variable soit déclarée en global ou en local, lorsque la fonction a fini de faire son travail, la variable et sa valeur à l'intérieur de la fonction, n'existent plus (à l'intérieur seulement bien sûr, car si vous l'avez déclarée à l'extérieur de la fonction, cette valeur externe subsiste toujours, nous l'avons vu). La place de la variable (à l'intérieur de la fonction) est libérée en mémoire. Lors d'un nouvel appel de la fonction, celle-ci recommence à faire ce pour quoi elle est faite, et tout recommence. Ça, on le sait. C'était juste un rappel.

Le mode "static", sert à faire en sorte que la variable conserve sa valeur à l'intérieur de la fonction, sans toucher à sa valeur à l'extérieur. Et ceci, quelque soit le nombre de fois où on fait appel à cette fonction dans le cours de l'exécution du programme contenu dans la page traitée par l'interpréteur PHP à un moment donné. Vous allez comprendre (moi même, j'ai eu quelque peu de mal à piger au début).
Soit le programme suivant où la variable $MonPrenom est déclarée et valorisée à l'extérieur de toute fonction et où l'on affiche sa valeur à l'intérieur de la fonction mais en lui rajoutant la chaîne de caractères "c'est moi". En plus, pour bien voir ce qui se passe, on va appeler cette fonction trois fois de suite et voir le résultat.

<?php

$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable à l'extérieur de la fonction

function AffichePrenom() { // début de la fonction AffichePrenom
$MonPrenom .= " c'est moi" ; // ajout de "c'est moi" à la variable à l'intérieur de la fonction
echo "A l'intérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'intérieur de la fonction

} // fin de la fonction AffichePrenom

AffichePrenom() ; // appel 1 de la fonction AffichePrenom
AffichePrenom() ; // appel 2 de la fonction AffichePrenom
AffichePrenom() ; // appel 3 de la fonction AffichePrenom
echo "A l'extérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'extérieur de la fonction

?>

Cliquez ICI pour voir le résultat.

Comme nous n'avons pas rendu la variable accessible à l'intérieur de la fonction par le petit mot magique "global", celle-ci (la variable) disparaît à chaque fin d'exécution de la fonction, et le résultat à l'écran est :

Appel 1 : Dans la fonction, la variable $MonPrenom contient la valeur : c'est moi
Appel 2 : Dans la fonction, la variable $MonPrenom contient la valeur : c'est moi
Appel 3 : Dans la fonction, la variable $MonPrenom contient la valeur : c'est moi
En dehors de la fonction, la variable $MonPrenom contient la valeur : Philippe

Bien entendu, la valeur à l'extérieur de la fonction n'est pas modifiée. Dans la fonction, la variable étant considérée comme purement locale et qu'on ne lui donne aucune valeur au début de la fonction, on ne fait que rajouter la chaîne de caractères "c'est moi" à du vide, ce qui donne ce que nous voyons. Jusque là, nous avons confirmation de ce que nous savons déjà. Parfait. Continuons.
Maintenant, déclarons notre variable en accès "global" à l'intérieur de la fonction. Ça, nous savons faire. Le programme devient :

<?php

$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable à l'extérieur de la fonction

function AffichePrenom() { // début de la fonction AffichePrenom
global $MonPrenom ; // déclaration de la variable en accès global pour cette fonction
$MonPrenom .= " c'est moi" ; // ajout de "c'est moi" à la variable à l'intérieur de la fonction
echo "A l'intérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'intérieur de la fonction

} // fin de la fonction AffichePrenom

AffichePrenom() ; // appel 1 de la fonction AffichePrenom
AffichePrenom() ; // appel 2 de la fonction AffichePrenom
AffichePrenom() ; // appel 3 de la fonction AffichePrenom
echo "A l'extérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'extérieur de la fonction

?>

Cliquez ICI pour voir le résultat.

Le résultat est

Appel 1 : Dans la fonction, la variable $MonPrenom contient la valeur : Philippe c'est moi
Appel 2 : Dans la fonction, la variable $MonPrenom contient la valeur : Philippe c'est moi c'est moi
Appel 3 : Dans la fonction, la variable $MonPrenom contient la valeur : Philippe c'est moi c'est moi c'est moi
En dehors de la fonction, la variable $MonPrenom contient la valeur : Philippe c'est moi c'est moi c'est moi

A chaque exécution de la fonction, la variable $MonPrenom étant accessible de partout par tout le monde, sa valeur est modifiée à l'intérieur comme à l'extérieur de la fonction à chaque passage. La première fois, on ajoute "c'est moi" à "Philippe" (contenu initial), la deuxième fois on rajoute encore "c'est moi", mais comme la valeur de la variable est devenue "Philippe c'est moi", ça donne "Philippe c'est moi c'est moi" et ainsi de suite.
Nous remarquons que plusieurs appels de cette fonction modifient la valeur de la variable $MonPrenom à l'extérieur de la fonction, si bien que celle-ci (la valeur) ne fait que croître et embellir, alors que la valeur initiale est perdue.

Voyons maintenant ce qui se passe si nous déclarons la variable $MonPrenom en "static" à l'intérieur de la fonction. Et en l'initialisant par la même occasion à la valeur "Philippe" (toujours à l'intérieur de la fonction, dans la même instruction). Notre programme devient :

<?php

$MonPrenom = "Philippe" ; // déclaration et valorisation de la variable à l'extérieur de la fonction

function AffichePrenom() { // début de la fonction AffichePrenom
static $MonPrenom = "Philippe"; // déclaration de la variable en static et valorisation à "Philippe" pour cette fonction
$MonPrenom .= " c'est moi" ; // ajout de "c'est moi" à la variable à l'intérieur de la fonction
echo "A l'intérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'intérieur de la fonction

} // fin de la fonction AffichePrenom

AffichePrenom() ; // appel 1 de la fonction AffichePrenom
AffichePrenom() ; // appel 2 de la fonction AffichePrenom
AffichePrenom() ; // appel 3 de la fonction AffichePrenom
echo "A l'extérieur de la fonction, la variable \$MonPrenom contient la valeur $MonPrenom" ; // affiche le contenu de la variable à l'extérieur de la fonction

?>

Cliquez ICI pour voir ce nouveau résultat.

Le résultat est :

Appel 1 : Dans la fonction, la variable $MonPrenom contient la valeur : Philippe c'est moi
Appel 2 : Dans la fonction, la variable $MonPrenom contient la valeur : Philippe c'est moi c'est moi
Appel 3 : Dans la fonction, la variable $MonPrenom contient la valeur : Philippe c'est moi c'est moi c'est moi
En dehors de la fonction, la variable $MonPrenom contient la valeur : Philippe

Où nous remarquons que tout se déroule comme précédemment, avec la différence que la valeur de la variable à l'extérieur de la fonction n'a pas bougé.

Conclusion, la déclaration en "static" d'une variable à l'intérieur d'une fonction fait que la valeur de cette variable est conservée à l'intérieur de cette fonction (et uniquement à l'intérieur) tout le temps que dure l'exécution du programme traité à un moment donné par l'interpréteur PHP. La valeur de la variable à l'extérieur de la fonction, ne bouge pas.

ATTENTION : si vous ne déclarez pas votre variable à l'extérieur de toute fonction (zone de déclaration des variables) mais seulement en "static" à l'intérieur d'une fonction, cette variable et sa valeur ne seront accessible qu'à l'intérieur de la fonction.
Aucune occurence de cette variable ne sera crée en externe de la fonction comme c'était le cas avec "global".

Pratique non ? Nous verrons ce que nous pouvons faire de cette "curiosité" plus tard, certainement.

 



Tableau de comparaison

Voici en résumé la comparaison de ces différents modes de déclaration des variables :
local
La variable est utilisable UNIQUEMENT à l'intérieur d'une fonction. Sa place et sa valeur sont détruites et l'emplacement mémoire récupéré à la fin de l'exécution de la fonction.
global
Nécessite de déclarer la variable par le mot réservé "global" à l'intérieur de la fonction. Les modifications apportées au contenu de cette variable sont répercutées aussi bien à l'intérieur de la fonction qu'à l'extérieur de celle-ci.
Une occurrence est automatiquement crée à l'extérieur de la fonction même si on n'a pas déclaré la variable en dehors de toute fonction.
static
La variable n'existe qu'à l'intérieur de la fonction. La valeur de la variable est conservée tout le temps de l'exécution du programme à l'intérieur de la fonction. Elle n'existe pas à l'extérieur si elle n'a pas été déclarée en dehors de toute fonction.

En conclusion, vous voyez qu'il est important de bien maîtriser la portée des variables si l'on veut obtenir les résultats désirés en écrivant un programme en PHP.



Ce cours est enseigné par Philippe Médan 
dans le cadre de la formation des professionnels de l'INTERNET.
au CREFAC , 14 rue Scandicci, 93000 Pantin. Tél. : 01 48 46 51 99
au GITA-GRETA , Lycée Technologique Diderot 61, rue David D'Angers 75019 Paris Tél. : 01 40 40 36 27
au CESI à l'Ecole des ingénieurs, 116 Av Aristide Briand, BP 57, 92224 Bagneux CEDEX Tél. : 01 45 36 70 00

© Philippe Médan 1999-2003. Tous droits de reproduction réservés pour tous pays.