Référence : Qu'est-ce que la portée d'une variable, quelles variables sont accessibles à partir d'où et qu'est-ce qu'une erreur de « variable non définie » ?
P粉018653751
2023-07-23 19:17:03
<p><br /></p><blockquote>
<p>Remarque : Il s'agit d'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 une copie de celle-ci.</p>
</blockquote>
<p>Que signifie la portée variable en PHP ? Les variables d'un fichier .php sont-elles accessibles dans un autre fichier ? Pourquoi est-ce que je reçois parfois un message d'erreur « variable non définie » ?</p>
Bien que les variables définies dans la portée d'une fonction ne soient pas accessibles de l'extérieur, cela ne signifie pas que leurs valeurs ne peuvent pas être utilisées une fois la fonction terminée. PHP possède un mot-clé static bien connu, qui est largement utilisé pour définir des méthodes et des propriétés statiques dans PHP orienté objet, mais vous devez vous rappeler que le mot-clé static peut également être utilisé pour définir des variables statiques dans une fonction.
Les variables statiques sont différentes des variables ordinaires définies dans la portée d'une fonction en ce sens qu'elles ne perdent pas leur valeur lorsque l'exécution du programme quitte la portée. Considérons l'exemple suivant utilisant des variables statiques :
Résultat :
Si nous n'utilisions pas le mot-clé static pour définir la variable $counter, la valeur sortie à chaque fois serait la même que le paramètre $num transmis à la fonction. L'utilisation du mot-clé static vous permet de créer ce compteur simple sans avoir besoin de solutions supplémentaires.
Objectif des variables statiques
Les variables statiques n'existent que dans la portée de la fonction locale. Il n'est pas accessible en dehors de la fonction dans laquelle il est défini. Par conséquent, vous pouvez vous assurer que sa valeur reste inchangée jusqu’au prochain appel à la fonction.
Les variables statiques ne peuvent être définies que comme des scalaires ou des expressions scalaires (depuis PHP 5.6). Lui attribuer d’autres valeurs entraînera forcément une erreur, du moins au moment d’écrire ces lignes. Cependant, vous pouvez le faire dans la ligne de code suivante :
Résultat :
Les fonctions statiques sont un mécanisme de "partage" entre méthodes objets d'une même classe. Cela peut être facilement compris en regardant les exemples suivants :
Cela ne fonctionne que pour les objets de la même classe. Si les objets appartiennent à des classes différentes (même s'ils s'étendent les uns aux autres), les variables statiques se comporteront comme prévu.
Les variables statiques sont-elles le seul moyen de conserver les valeurs entre les appels de 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 termes simples, ils vous permettent de restreindre l'accès à un certain ensemble de variables à une autre fonction anonyme dans le cadre de la fonction, qui sera le seul moyen d'accéder à ces variables. Au sein des fermetures, les variables peuvent émuler (plus ou moins avec succès) les concepts de « constantes de classe » (si elles sont transmises à la fermeture par valeur) ou de « propriétés privées » (si passées par référence) dans la programmation orientée objet.
En fait, cette dernière permet l'utilisation de fermetures au lieu de variables statiques. La méthode à utiliser dépend entièrement de la décision du développeur, mais il convient de mentionner que les variables statiques sont très utiles lorsqu'il s'agit de récursivité et méritent l'attention du développeur.
Qu'est-ce que la portée variable
Les variables ont une « portée » limitée ou « l'endroit où elles sont accessibles ». Ce n'est pas parce que vous avez écrit $foo = 'bar'; une fois quelque part dans votre application que vous pouvez référencer $foo ailleurs dans votre application. La variable $foo est valide dans une portée spécifique et n'est accessible que par du code dans la même portée.
Comment définir la portée en PHP ?
Très simple : PHP a une portée fonctionnelle. C'est le seul délimiteur de portée qui existe en PHP. Les variables à l'intérieur d'une fonction ne peuvent être utilisées que dans cette fonction. Les variables en dehors d'une fonction peuvent être utilisées n'importe où en dehors de la fonction, mais ne peuvent pas être utilisées dans une fonction. Cela signifie qu'il existe une portée spéciale en PHP : la portée globale. Les variables déclarées en dehors de toute fonction sont dans la portée globale.
Par exemple :
.$foo
is in the global scope,$baz
is in a local scope insidemyFunc
. Only code insidemyFunc
has access to$baz
. Only code outsidemyFunc
has access to$foo
Aucun des deux n'a accès à l'autre :Portées et fichiers inclus
Les limites des fichiers ne séparent pas les étendues.
a.php
b.php
Les règles qui s'appliquent au code inclus sont les mêmes que celles qui s'appliquent à tout autre code : seules les fonctions peuvent séparer les portées. En termes de portée, vous pouvez considérer l'inclusion de fichiers sous forme de copier-coller de code.
c.php
Dans l'exemple ci-dessus, a.php est contenu dans myFunc et toutes les variables de a.php n'ont qu'une portée de fonction locale. Ce n'est pas parce qu'ils semblent avoir une portée globale dans a.php qu'ils le sont réellement, cela dépend vraiment du contexte dans lequel ce code est inclus/exécuté.
Concernant les fonctions et les classes à l'intérieur des fonctions, comment est gérée une autre situation ?
Chaque nouvelle déclaration de fonction introduit une nouvelle portée, c'est aussi simple que cela.
Fonctions (anonymes) à l’intérieur des fonctions.
Catégorie
À quoi sert la portée ?
Gérer les problèmes de portée peut sembler ennuyeux, mais des portées de variables limitées sont cruciales pour écrire des applications complexes ! Si chaque variable que vous déclarez dans votre application est accessible de n'importe où, vous ne pourrez pas suivre les modifications apportées à la variable. Vous ne pouvez donner aux variables qu'un nombre limité de noms sensés et vous souhaiterez peut-être utiliser la variable "$name" à plusieurs endroits. Si vous ne pouvez avoir qu'un seul nom de variable unique dans votre application, vous devrez utiliser un schéma de dénomination très complexe pour garantir l'unicité des variables et vous assurer de ne pas modifier la mauvaise variable à partir du mauvais morceau de code.
Comme suit :
Que ferait la fonction ci-dessus s'il n'y avait pas de portée ? D'où vient $bar ? Quel statut a-t-il ? Est-il initialisé ? Faut-il vérifier à chaque fois ? Ce n'est pas maintenable. Ce qui nous amène à...
Traverser les limites du champ d'application
La bonne façon : transmettre des variables d'entrée et de sortie
La variable $bar est explicitement passée dans la portée en tant que paramètre de fonction. Rien qu'en regardant cette fonction, il est clair d'où viennent les valeurs qu'elle utilise. Ensuite, il renvoie explicitement une valeur. L'appelant peut être sûr des variables que la fonction utilisera et d'où vient la valeur de retour :
Étendez la portée des variables aux fonctions anonymes
Les fonctions anonymes incluent explicitement la variable $foo de sa portée environnante. Notez que ce n’est pas la même chose que la portée globale.
Mauvais chemin :
global
Comme mentionné précédemment, la portée globale est spéciale et les fonctions peuvent importer explicitement des variables depuis la portée globale :
Cette fonction utilise et modifie la variable globale $foo. Ne faites pas cela! (À moins que vous sachiez vraiment vraiment ce que vous faites, et encore : ne le faites pas !)
L'appelant de cette fonction ne verra que ceci :
Rien n’indique que cette fonction ait des effets secondaires, mais c’est effectivement le cas. Cela peut facilement se transformer en une situation compliquée lorsque certaines fonctions sont constamment modifiées et dépendent d'un état global. Vous souhaitez que la fonction soit sans état, fonctionnant uniquement sur ses entrées et renvoyant des sorties définies, quel que soit le nombre de fois que vous l'appelez.
Évitez d'utiliser la portée globale en toutes circonstances si possible ; en particulier, les variables ne doivent pas être "extraites" de la portée globale vers la portée locale.