Remarque: Ceci est une question de référence pour traiter la portée des variables en PHP. Veuillez fermer l'une des nombreuses questions correspondant à ce modèle comme un double de celui-ci.
Qu'est-ce que la "portée variable" en PHP? Les variables d'un fichier .php sont-elles accessibles dans un autre? Pourquoi ai-je parfois des erreurs "variable non définie" ?
Réponses:
Qu'est-ce qu'une "portée variable"?
Les variables ont une «portée» limitée, ou des «endroits à partir desquels elles sont accessibles». Ce n'est pas parce que vous avez écrit
$foo = 'bar';
une fois quelque part dans votre application que vous pouvez vous référer$foo
de partout ailleurs dans l'application. La variable$foo
a une certaine portée dans laquelle elle est valide et seul le code de la même portée a accès à la variable.Comment une portée est-elle définie en PHP?
Très simple: PHP a une portée fonctionnelle . C'est le seul type de séparateur de portée qui existe en PHP. Les variables à l'intérieur d'une fonction ne sont disponibles qu'à l'intérieur de cette fonction. Les variables en dehors des fonctions sont disponibles n'importe où en dehors des fonctions, mais pas à l'intérieur d'une fonction. Cela signifie qu'il y a une portée spéciale en PHP: la portée globale . Toute variable déclarée en dehors de toute fonction est dans cette portée globale.
Exemple:
$foo
est dans la portée globale ,$baz
est dans une portée locale à l' intérieurmyFunc
. Seul le code à l'intérieurmyFunc
a accès à$baz
. Seul le code extérieurmyFunc
a accès à$foo
. Aucun n'a accès à l'autre:Portée et fichiers inclus
Les limites des fichiers ne séparent pas la portée:
a.php
b.php
Les mêmes règles s'appliquent au
include
code d que pour tout autre code: seulementfunction
une portée distincte. Aux fins de la portée, vous pouvez penser à inclure des fichiers tels que copier-coller du code:c.php
Dans l'exemple ci-dessus, a
a.php
été inclus à l'intérieurmyFunc
, toutes les variables à l'intérieura.php
n'ont qu'une portée de fonction locale. Ce n'est pas parce qu'ils semblent être dans la portée globale dea.php
cela que cela signifie nécessairement qu'ils le sont, cela dépend en fait du contexte dans lequel le code est inclus / exécuté.Qu'en est-il des fonctions à l'intérieur des fonctions et des classes?
Chaque nouvelle
function
déclaration introduit une nouvelle portée, c'est aussi simple que cela.(anonyme) fonctions à l'intérieur des fonctions
Des classes
À quoi sert la portée?
Traiter les problèmes de cadrage peut sembler ennuyeux, mais une portée variable limitée est essentielle pour écrire des applications complexes! Si chaque variable que vous déclarez était disponible partout ailleurs dans votre application, vous parcourriez toutes vos variables sans véritable moyen de suivre ce qui change quoi. Il n'y a qu'un nombre limité de noms sensés que vous pouvez donner à vos variables, vous voudrez probablement utiliser la variable "
$name
" à plus d'un endroit. Si vous ne pouviez avoir ce nom de variable unique qu'une seule fois dans votre application, vous devrez recourir à des schémas de dénomination très compliqués pour vous assurer que vos variables sont uniques et que vous ne changez pas la mauvaise variable du mauvais morceau de code.Observer:
S'il n'y avait pas de portée, que ferait la fonction ci-dessus? D'où
$bar
vient-il? Quel état a-t-il? Est-il même initialisé? Devez-vous vérifier à chaque fois? Ce n'est pas maintenable. Ce qui nous amène à ...Traverser les limites de la portée
La bonne façon: faire entrer et sortir des variables
La variable
$bar
entre explicitement dans cette portée en tant qu'argument de fonction. En regardant simplement cette fonction, il est clair d'où proviennent les valeurs avec lesquelles elle fonctionne. Il renvoie ensuite explicitement une valeur. L'appelant a la confiance nécessaire pour savoir avec quelles variables la fonction fonctionnera et d'où viennent ses valeurs de retour:Extension de la portée des variables aux fonctions anonymes
La fonction anonyme inclut explicitement
$foo
de sa portée environnante. Notez que ce n'est pas la même chose que la portée globale .La mauvaise direction:
global
Comme indiqué précédemment, la portée globale est quelque peu spéciale et les fonctions peuvent en importer explicitement des variables:
Cette fonction utilise et modifie la variable globale
$foo
. Ne faites pas cela! (À moins que vous ne sachiez vraiment vraiment vraiment ce que vous faites, et même alors: ne le faites pas!)Tout ce que voit l'appelant de cette fonction est ceci:
Rien n'indique que cette fonction ait des effets secondaires , mais c'est le cas. Cela devient très facilement un désordre enchevêtré car certaines fonctions continuent de se modifier et nécessitent un état global. Vous voulez que les fonctions soient sans état , agissant uniquement sur leurs entrées et renvoyant une sortie définie, quel que soit le nombre de fois que vous les appelez.
Vous devez éviter autant que possible d'utiliser la portée globale; vous ne devriez certainement pas "extraire" des variables de la portée globale vers une portée locale.
la source
global
, alors dites-nous quand devrions-nous utiliserglobal
? Et expliquez (un peu) ce que c'eststatic
..?global
. C'est toujours faux. Passer des paramètres de fonction est juste.static
est bien expliqué dans le manuel et n'a pas grand chose à voir avec la portée. En un mot, il peut être considéré comme une «variable globale de portée». Je développe un peu son utilisation ici kunststube.net/static .include_once
etrequire_once
devrait peut -être aussi être ajouté quelque part; juste en disant. OP a également voté pour rouvrir sa question. Leur publication constituerait-elle un cas particulier et que faudrait-il faire à ce sujet?Bien que les variables définies à l'intérieur de la portée d'une fonction ne soient pas accessibles de l'extérieur, cela ne signifie pas que vous ne pouvez pas utiliser leurs valeurs une fois la fonction terminée. PHP a un
static
mot-clé bien connu qui est largement utilisé dans PHP orienté objet pour définir des méthodes et des propriétés statiques, mais il faut garder à l'esprit qu'ilstatic
peut également être utilisé à l'intérieur de fonctions pour définir des variables statiques.Qu'est-ce que c'est «variable statique»?
La variable statique diffère de la variable ordinaire définie dans la portée de la fonction dans le cas où elle ne perd pas de valeur lorsque l'exécution du programme quitte cette portée. Prenons l'exemple suivant d'utilisation de variables statiques:
Résultat:
Si nous avions défini
$counter
sansstatic
alors chaque fois la valeur écho serait la même que le$num
paramètre passé à la fonction. L'utilisationstatic
permet de créer ce compteur simple sans solution de contournement supplémentaire.Cas d'utilisation des variables statiques
Des trucs
La variable statique n'existe que dans une portée de fonction locale. Il n'est pas accessible en dehors de la fonction dans laquelle il a été défini. Vous pouvez donc être sûr qu'il conservera sa valeur inchangée jusqu'au prochain appel à cette fonction.
La variable statique ne peut être définie que comme un scalaire ou comme une expression scalaire (depuis PHP 5.6). Lui attribuer d'autres valeurs conduit inévitablement à un échec au moins au moment de la rédaction de cet article. Néanmoins, vous pouvez le faire uniquement sur la ligne suivante de votre code:
Résultat:
La fonction statique est un peu «partagée» entre les méthodes d'objets de la même classe. Il est facile à comprendre en consultant l'exemple suivant:
Cela ne fonctionne qu'avec des objets de la même classe. Si les objets sont de classes différentes (même s'étendant les uns les autres), le comportement des variables statiques sera comme prévu.
La variable statique est-elle le seul moyen de conserver les valeurs entre les appels à une fonction?
Une autre façon de conserver les valeurs entre les appels de fonction consiste à utiliser des fermetures. Les fermetures ont été introduites dans PHP 5.3. En deux mots, ils vous permettent de limiter l'accès à un ensemble de variables dans une portée de fonction à une autre fonction anonyme qui sera le seul moyen d'y accéder. Être dans des variables de fermeture peut imiter (avec plus ou moins de succès) des concepts de POO comme les «constantes de classe» (si elles ont été passées en fermeture par valeur) ou les «propriétés privées» (si elles sont passées par référence) dans la programmation structurée.
Ce dernier permet en fait d'utiliser des fermetures au lieu de variables statiques. Ce qu'il faut utiliser est toujours au développeur de décider, mais il convient de mentionner que les variables statiques sont vraiment utiles lorsque vous travaillez avec des récursions et méritent d'être remarquées par les développeurs.
la source
Je ne publierai pas de réponse complète à la question, car les versions existantes et le manuel PHP font un excellent travail pour expliquer la plupart de cela.
Mais un sujet qui a été manquée était celle de superglobales , y compris le couramment utilisé
$_POST
,$_GET
,$_SESSION
, etc. Ces variables sont des tableaux qui sont toujours disponibles, dans une portée, sansglobal
déclaration.Par exemple, cette fonction affichera le nom de l'utilisateur exécutant le script PHP. La variable est disponible pour la fonction sans aucun problème.
La règle générale «les globaux sont mauvais» est généralement modifiée en PHP en «les globaux sont mauvais mais les superglobals sont bien», tant qu'on ne les utilise pas à mauvais escient. (Toutes ces variables sont inscriptibles, elles pourraient donc être utilisées pour éviter l'injection de dépendances si vous étiez vraiment terrible.)
La présence de ces variables n'est pas garantie; un administrateur peut désactiver certains d'entre eux ou tous à l'aide de la
variables_order
directive inphp.ini
, mais ce n'est pas un comportement courant.Une liste des superglobales actuelles:
$GLOBALS
- Toutes les variables globales du script courant$_SERVER
- Informations sur le serveur et l'environnement d'exécution$_GET
- Valeurs passées dans la chaîne de requête de l'URL, quelle que soit la méthode HTTP utilisée pour la requête$_POST
- Valeurs passées dans une requête HTTP POST avecapplication/x-www-form-urlencoded
oumultipart/form-data
types MIME$_FILES
- Fichiers passés dans une requête HTTP POST avec unmultipart/form-data
type MIME$_COOKIE
- Cookies transmis avec la demande en cours$_SESSION
- Variables de session stockées en interne par PHP$_REQUEST
- Généralement une combinaison de$_GET
et$_POST
, mais parfois$_COOKIES
. Le contenu est déterminé par larequest_order
directive dansphp.ini
.$_ENV
- Les variables d'environnement du script courantla source