function foo () {
global $var;
// rest of code
}
Dans mes petits projets PHP, j'utilise généralement la méthode procédurale. J'ai généralement une variable qui contient la configuration du système, et quand je veux accéder à cette variable dans une fonction, je le fais global $var;
.
Est-ce une mauvaise pratique?
php
global-variables
global
KRTac
la source
la source
Réponses:
Lorsque les gens parlent de variables globales dans d'autres langues, cela signifie quelque chose de différent de ce que cela fait en PHP. C'est parce que les variables ne sont pas vraiment globales en PHP. La portée d'un programme PHP typique est une requête HTTP. Les variables de session ont en fait une portée plus large que les variables "globales" PHP car elles englobent généralement de nombreuses requêtes HTTP.
Souvent (toujours?), Vous pouvez appeler des fonctions membres dans des méthodes comme
preg_replace_callback()
celle-ci:preg_replace_callback('!pattern!', array($obj, 'method'), $str);
Voir les rappels pour en savoir plus.
Le fait est que les objets ont été boulonnés sur PHP et conduisent à certains égards à une certaine maladresse.
Ne vous préoccupez pas trop de l'application de normes ou de constructions de différents langages à PHP. Un autre piège courant consiste à essayer de transformer PHP en un pur langage POO en collant des modèles d'objets au-dessus de tout.
Comme toute autre chose, utilisez des variables «globales», du code procédural, un cadre particulier et une POO car cela a du sens, résout un problème, réduit la quantité de code à écrire ou le rend plus maintenable et plus facile à comprendre, pas parce que vous pensez vous devriez.
la source
array ($obj, 'callbackMethod')
dans les appels àpreg_replace_callback()
? (Je sais, je suis la proie de cet écueil de POO ...)Les variables globales, si elles ne sont pas utilisées avec soin, peuvent rendre les problèmes plus difficiles à trouver. Disons que vous demandez un script php et que vous recevez un avertissement indiquant que vous essayez d'accéder à un index d'un tableau qui n'existe pas dans une fonction.
Si le tableau auquel vous essayez d'accéder est local à la fonction, vous vérifiez la fonction pour voir si vous y avez fait une erreur. Cela peut être un problème avec une entrée de la fonction afin que vous vérifiez les endroits où la fonction est appelée.
Mais si ce tableau est global, vous devez vérifier tous les endroits où vous utilisez cette variable globale, et pas seulement cela, vous devez déterminer dans quel ordre ces références à la variable globale sont accédées.
Si vous avez une variable globale dans un morceau de code, il est difficile d'isoler la fonctionnalité de ce code. Pourquoi voudriez-vous isoler les fonctionnalités? Vous pouvez donc le tester et le réutiliser ailleurs. Si vous avez du code que vous n'avez pas besoin de tester et que vous n'avez pas besoin de réutiliser, alors utiliser des variables globales est très bien.
la source
je suis d'accord avec cletus. j'ajouterais deux choses:
Meilleures salutations, don
la source
$DB = 'foo';
Qui peut s'opposer à l'expérience, aux diplômes universitaires et au génie logiciel? Pas moi. Je dirais seulement qu'en développant des applications PHP mono-page orientées objet, je m'amuse plus quand je sais que je peux tout construire à partir de zéro sans me soucier des collisions d'espace de noms. Construire à partir de zéro est quelque chose que beaucoup de gens ne font plus. Ils ont un travail, une date limite, un bonus ou une réputation dont ils doivent se soucier. Ces types ont tendance à utiliser tellement de code pré-construit avec des enjeux élevés, qu'ils ne peuvent pas risquer du tout d'utiliser des variables globales.
Il peut être mauvais d'utiliser des variables globales, même si elles ne sont utilisées que dans la zone globale d'un programme, mais n'oublions pas ceux qui veulent juste s'amuser et faire fonctionner quelque chose .
Si cela signifie utiliser quelques variables (<10) dans l'espace de noms global, qui ne sont utilisées que dans la zone globale d'un programme, qu'il en soit ainsi. Oui, oui, MVC, injection de dépendance, code externe, bla, bla, bla, bla. Mais, si vous avez contenu 99,99% de votre code dans des espaces de noms et des classes, et que le code externe est en bac à sable, le monde ne s'arrêtera pas (je le répète, le monde ne s'arrêtera pas) si vous utilisez une variable globale.
En général, je ne dirais pas que l'utilisation de variables globales est une mauvaise pratique . Je dirais que l'utilisation de variables globales (drapeaux et autres) en dehors de la zone globale d'un programme pose des problèmes et (à long terme) est déconseillé car vous pouvez perdre la trace de leurs états assez facilement. Aussi, je dirais que plus vous apprenez, moins vous serez dépendant des variables globales car vous aurez expérimenté la "joie" de traquer les bogues associés à leur utilisation. Cela seul vous incitera à trouver un autre moyen de résoudre le même problème. Par coïncidence, cela tend à pousser les personnes PHP dans le sens de l'apprentissage de l'utilisation des espaces de noms et des classes (membres statiques, etc ...).
Le domaine de l'informatique est vaste. Si nous effrayons tout le monde de faire quelque chose parce que nous le qualifions de mauvais , alors ils perdent le plaisir de vraiment comprendre le raisonnement derrière l'étiquette.
Utilisez des variables globales si nécessaire, mais voyez ensuite si vous pouvez résoudre le problème sans elles. Les collisions, les tests et le débogage signifient plus lorsque vous comprenez intimement la vraie nature du problème, pas seulement une description du problème.
la source
Nous pouvons illustrer ce problème avec le pseudo-code suivant
function foo() { global $bob; $bob->doSomething(); }
Votre première question ici est évidente
Êtes-vous confus? Bien. Vous venez d'apprendre pourquoi les globaux sont déroutants et considérés comme une mauvaise pratique. S'il s'agissait d'un vrai programme, votre prochain plaisir est de rechercher toutes les instances de
$bob
et d'espérer que vous trouverez le bon (cela s'aggrave s'il$bob
est utilisé partout). Pire encore, si quelqu'un d'autre définit$bob
(ou si vous avez oublié et réutilisé cette variable), votre code peut casser (dans l'exemple de code ci-dessus, avoir le mauvais objet, ou aucun objet du tout, provoquerait une erreur fatale). Puisque pratiquement tous les programmes PHP utilisent du code commeinclude('file.php');
votre travail, maintenir un code comme celui-ci devient exponentiellement plus difficile à mesure que vous ajoutez de fichiers.Comment éviter les globaux?
La meilleure façon d'éviter les globaux est une philosophie appelée injection de dépendance . C'est là que nous transmettons les outils dont nous avons besoin à la fonction ou à la classe.
function foo(\Bar $bob) { $bob->doSomething(); }
C'est beaucoup plus facile à comprendre et à maintenir. Il est impossible de deviner où a
$bob
été configuré car l'appelant est responsable de le savoir (il nous transmet ce que nous devons savoir). Mieux encore, nous pouvons utiliser des déclarations de type pour restreindre ce qui est passé. Nous savons donc que$bob
c'est soit une instance de laBar
classe, soit une instance d'un enfant deBar
, ce qui signifie que nous savons que nous pouvons utiliser les méthodes de cette classe. Combiné à un autoloader standard (disponible depuis PHP 5.3), on peut désormais aller traquer oùBar
est défini. PHP 7.0 ou version ultérieure inclut des déclarations de type étendues, où vous pouvez également utiliser des types scalaires (commeint
oustring
).la source
$bob = Bar::instance();
quand vous en avez besoin.Comme:
global $my_global; $my_global = 'Transport me between functions'; Equals $GLOBALS['my_global']
est une mauvaise pratique (comme Wordpress
$pagenow
) ... hmmmConsidérez ceci:
$my-global = 'Transport me between functions';
est une erreur PHP Mais:
$GLOBALS['my-global'] = 'Transport me between functions';
n'est PAS une erreur, les hypens ne seront pas en conflit avec les variables déclarées par l'utilisateur "communes", comme
$pagenow
. Et l'utilisation de MAJUSCULES indique un superglobal en cours d'utilisation, facile à repérer dans le code, ou à suivre avec recherche dans les fichiersJ'utilise des traits d'union, si je suis paresseux pour créer des classes de tout pour une seule solution, comme:
$GLOBALS['PREFIX-MY-GLOBAL'] = 'Transport me ... ';
Mais dans les cas d'une utilisation plus large, j'utilise ONE globals comme tableau:
$GLOBALS['PREFIX-MY-GLOBAL']['context-something'] = 'Transport me ... '; $GLOBALS['PREFIX-MY-GLOBAL']['context-something-else']['numbers'][] = 'Transport me ... ';
Ce dernier est pour moi, une bonne pratique sur les objectifs «cola light» ou à utiliser, au lieu de l'encombrement de classes singleton à chaque fois pour «mettre en cache» certaines données. Veuillez faire un commentaire si je me trompe ou si je manque quelque chose de stupide ici ...
la source