Maison > Questions et réponses > le corps du texte
P粉7864325792023-07-24 11:19:34
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 :
function countSheep($num) { static $counter = 0; $counter += $num; echo "$counter sheep jumped over fence"; } countSheep(1); countSheep(2); countSheep(3);
Résultat :
1 sheep jumped over fence 3 sheep jumped over fence 6 sheep jumped over fence
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.
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 :
function countSheep($num) { static $counter = 0; $counter += sqrt($num);//imagine we need to take root of our sheep each time echo "$counter sheep jumped over fence"; }
Résultat :
2 sheep jumped over fence 5 sheep jumped over fence 9 sheep jumped over fence
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 :
class SomeClass { public function foo() { static $x = 0; echo ++$x; } } $object1 = new SomeClass; $object2 = new SomeClass; $object1->foo(); // 1 $object2->foo(); // 2 oops, $object2 uses the same static $x as $object1 $object1->foo(); // 3 now $object1 increments $x $object2->foo(); // 4 and now his twin brother
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.
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.
P粉5746952152023-07-24 09:30:10
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.
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.
<?php $foo = 'bar'; function myFunc() { $baz = 42; }
$foo
is in the global scope, $baz
is in a local scope inside myFunc
. Only code inside myFunc
has access to $baz
. Only code outside myFunc
has access to $foo
Aucun des deux n'a accès à l'autre :
<?php $foo = 'bar'; function myFunc() { $baz = 42; echo $foo; // doesn't work echo $baz; // works } echo $foo; // works echo $baz; // doesn't work
Les limites des fichiers ne séparent pas les étendues.
a.php
<?php $foo = 'bar';
b.php
<?php include 'a.php'; echo $foo; // works!
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
<?php function myFunc() { include 'a.php'; echo $foo; // works } myFunc(); echo $foo; // doesn't work!
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é.
Chaque nouvelle déclaration de fonction introduit une nouvelle portée, c'est aussi simple que cela.
function foo() { $foo = 'bar'; $bar = function () { // no access to $foo $baz = 'baz'; }; // no access to $baz }
$foo = 'foo'; class Bar { public function baz() { // no access to $foo $baz = 'baz'; } } // 无法访问 $baz。
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 :
function foo() { echo $bar; }
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 à...
function foo($bar) { echo $bar; return 42; }
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 :
$baz = 'baz'; $blarg = foo($baz);
$foo = 'bar'; $baz = function () use ($foo) { echo $foo; }; $baz();
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.
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 :
$foo = 'bar'; function baz() { global $foo; echo $foo; $foo = 'baz'; }
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 :
baz(); // outputs "bar" unset($foo); baz(); // no output, WTF?! baz(); // outputs "baz", WTF?!?!!
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.