Globales PHP - Quand les utiliser et les éviter ?

Étienne Lambert .

12 mai 2026

Graphique comparant des frameworks PHP (Symfony, Laravel, CakePHP, etc.) selon leur maturité et complexité. Utile pour choisir un framework, même si les variables globales PHP ne sont pas directement représentées.

Dans un backend PHP, le vrai sujet n’est pas de savoir si une donnée peut être partagée partout, mais de comprendre qui la lit, qui la modifie et à quel moment. Je vais clarifier la portée des variables, distinguer `global`, `$GLOBALS` et les superglobales, puis montrer dans quels cas je les accepte encore dans une API et dans quels cas je les évite franchement.

Les points essentiels à garder en tête avant d’utiliser un global

  • Une variable globale n’est pas visible partout automatiquement dans le code des fonctions.
  • `global` expose une variable du scope global à l’intérieur d’une fonction, tandis que `$GLOBALS` permet d’y accéder via un tableau superglobal.
  • Les superglobales comme `$_GET`, `$_POST` et `$_SERVER` sont disponibles partout, mais elles contiennent des données externes à valider.
  • Dans une API, les variables globales cachent les dépendances et rendent les tests plus fragiles.
  • Pour du code moderne, je privilégie les arguments, les objets de contexte et l’injection de dépendances.

Ce qu’il faut garder en tête avant de toucher au global

En PHP, une variable déclarée en dehors d’une fonction appartient au scope global, mais elle n’est pas automatiquement visible à l’intérieur d’une fonction. C’est souvent là que les débutants se trompent : le fichier entier ne se comporte pas comme un seul bloc homogène, chaque fonction a sa propre portée locale. Je le rappelle toujours parce qu’une bonne partie des bugs “inexplicables” viennent simplement d’un accès hors scope.

Dans un backend classique exécuté via PHP-FPM ou un serveur web traditionnel, l’état global ne traverse généralement pas les requêtes. Autrement dit, un global peut servir à partager une valeur dans un script pendant une requête, mais pas à stocker durablement l’état d’un utilisateur ou d’une application. Si vous avez besoin de persister une information, la bonne cible est plutôt la session, un cache, une base de données ou un stockage dédié.

Cette séparation entre portée locale et portée globale est la base du reste. Une fois qu’on la maîtrise, la différence entre `global`, `$GLOBALS` et les superglobales devient beaucoup plus lisible.

Utiliser `global` et `$GLOBALS` sans les confondre

Le mot-clé `global` permet d’importer une variable du scope global à l’intérieur d’une fonction. `$GLOBALS`, lui, donne un accès direct au tableau associatif de toutes les variables globales disponibles. La documentation PHP rappelle d’ailleurs que les superglobales sont accessibles dans toutes les portées, sans déclaration préalable.

Les deux approches fonctionnent, mais je ne les mets pas au même niveau. `global` est plus compact, tandis que `$GLOBALS` rend l’accès plus explicite, au prix d’un code plus verbeux. Dans les deux cas, la dépendance reste cachée dans le corps de la fonction plutôt que dans sa signature, et c’est précisément ce qui me gêne dans un projet qui doit évoluer.

Mécanisme Disponible où Usage utile Limite principale
global À l’intérieur d’une fonction après déclaration Refonte rapide d’un code procédural ancien Dépendance implicite, tests plus difficiles
$GLOBALS Partout dans le script Accès explicite à une variable globale existante Couplage fort au symbol table, usage peu élégant
Superglobales Dans tous les scopes Données de requête, environnement, session Ce sont des entrées externes, pas de l’état métier
$_REQUEST Dans tous les scopes Cas très spécifiques et scripts simples Origine des données ambiguë, donc moins lisible

Point technique utile : depuis PHP 8.1, une copie de `$GLOBALS` ne se comporte plus comme auparavant pour modifier les variables globales via cette copie. Je vois ce changement comme un bon rappel du fait que ce mécanisme n’a jamais été une base solide pour une architecture propre. C’est aussi pour cela que, dans un code moderne, je préfère réduire au maximum son usage.

Quand le global reste acceptable dans un backend

Je ne considère pas les variables globales comme interdites par principe. Elles restent parfois pratiques dans trois cas précis : un script court, une refonte progressive d’un code hérité, ou un outil de maintenance qui doit rester simple. Dans ces situations, le bénéfice immédiat peut dépasser le coût architectural, à condition de garder le périmètre très petit.

  • Dans un script de migration ponctuel, un état partagé temporaire peut éviter une sur-ingénierie inutile.
  • Dans un vieux projet procédural, je peux tolérer un global comme étape de transition, pas comme solution finale.
  • Dans un bootstrap de configuration, une valeur lue une seule fois et ensuite traitée en lecture seule peut rester acceptable si le code est court.
  • Dans un outil CLI simple, la portée globale peut dépanner, surtout si le script vit peu longtemps et n’a pas d’utilisateur concurrent.

En revanche, dès qu’on parle d’API publique, de logique métier partagée ou de code appelé depuis plusieurs couches, la tolérance baisse vite. À ce niveau, le global cesse d’être un raccourci pratique et devient une source de couplage. La prochaine question logique est donc : qu’est-ce qui casse réellement quand on en abuse ?

Les pièges qui coûtent du temps en débogage

Le premier problème, ce n’est pas la syntaxe. C’est le couplage caché. Une fonction qui dépend d’une variable globale peut sembler pure à la lecture, alors qu’elle ne l’est pas du tout. Quand je relis ce genre de code, je dois remonter ailleurs pour comprendre d’où vient la donnée, et ce temps perdu se paie ensuite en tests plus lourds, en bugs plus subtils et en refontes plus coûteuses.

Mauvais réflexe Effet concret Ce que je fais à la place
Lire et écrire la même globale depuis plusieurs fonctions Effets de bord difficiles à anticiper Passer la valeur en argument ou l’encapsuler dans un objet
Utiliser `$_REQUEST` pour aller plus vite Origine des données floue Choisir explicitement `$_GET`, `$_POST` ou `$_COOKIE` selon le besoin
Tirer de la logique métier directement depuis `$_GET` ou `$_POST` Code lié à HTTP au lieu d’être lié au domaine Normaliser les entrées au bord de l’application
Conserver de l’état mutable dans un process persistant Fuites de contexte entre requêtes Réinitialiser le contexte à chaque requête ou éviter l’état partagé

Sur le plan sécurité, je suis également strict : les superglobales d’entrée représentent des données externes, pas des valeurs de confiance. Il faut donc filtrer, valider et normaliser tôt, avant que la donnée n’entre dans le cœur du backend. Cette discipline évite de transformer un simple accès à une variable en point d’entrée pour des comportements imprévisibles.

Ce que je préfère à la place dans un projet moderne

Dans un projet backend ou API, je privilégie presque toujours des dépendances explicites. Si une fonction a besoin d’une valeur, je lui passe cette valeur. Si plusieurs fonctions ont besoin du même ensemble de paramètres, je regroupe ces paramètres dans un objet de contexte ou un service dédié. Le résultat est plus lisible, plus testable et plus facile à refactorer.

Cette version dit tout dès la signature : la fonction dépend de `appName` et de `path`. Je peux la tester sans préparer un état global préalable, et je peux la déplacer dans un autre service sans casser silencieusement son comportement.

  • Arguments de fonction pour faire circuler les données de façon explicite.
  • Objets de contexte pour regrouper plusieurs valeurs liées, comme la configuration ou l’identité de requête.
  • Injection de dépendances pour les services, les loggers, les clients HTTP ou les accès externes.
  • Session, cache ou base de données si la donnée doit survivre à plusieurs requêtes.
  • Variables `static` locales seulement pour un cache interne très ciblé, jamais pour simuler un état applicatif global.

La nuance importante, c’est que tout n’a pas besoin d’être un objet gigantesque. Un simple tableau de configuration en lecture seule peut suffire dans beaucoup de scripts. Ce qui compte, c’est que la dépendance soit visible et contrôlable, pas cachée derrière un accès implicite à un état partagé.

La règle simple que j’applique avant d’introduire un global

Je me pose toujours la même question : puis-je comprendre cette fonction sans aller chercher ailleurs une variable cachée ? Si la réponse est non, je privilégie une dépendance explicite. Cette règle me paraît plus fiable que n’importe quel réflexe de confort, parce qu’elle protège à la fois la lisibilité, les tests et l’évolution du code.

  • Si la donnée sert à une seule fonction, je la passe en paramètre.
  • Si plusieurs couches en ont besoin, je crée un contexte ou un service dédié.
  • Si la donnée doit vivre au-delà d’une requête, je choisis un stockage adapté, pas un global.
  • Si je dois garder un global dans un héritage procédural, je le limite, je le documente et je prépare sa suppression.

Dans une API, cette discipline fait vite la différence entre un code qui “marche” et un code qu’on peut encore faire évoluer dans six mois. Quand la dépendance est visible dans la signature, je lis le programme plus vite, je le teste plus vite, et je corrige les erreurs sans devoir deviner ce que cachait le scope global.

Questions fréquentes

Le mot-clé `global` importe une variable du scope global dans une fonction. `$GLOBALS` est un tableau superglobal qui donne accès à toutes les variables globales. Tandis que `global` est plus concis, `$GLOBALS` est plus explicite mais rend le code plus verbeux.
Non, pas toujours. Elles peuvent être acceptables pour des scripts courts, la refonte de code hérité ou des outils de maintenance simples. Cependant, dans les API ou la logique métier complexe, elles introduisent un couplage caché et rendent le code difficile à tester et à maintenir.
Les superglobales contiennent des données provenant de sources externes (requêtes utilisateur, environnement). Elles ne sont pas fiables par défaut et doivent être filtrées, validées et normalisées avant d'être utilisées dans le cœur de l'application pour éviter des failles de sécurité ou des comportements imprévus.
Privilégiez les arguments de fonction pour passer les données explicitement. Utilisez des objets de contexte pour regrouper des valeurs liées et l'injection de dépendances pour les services. Pour les données persistantes, optez pour la session, le cache ou une base de données plutôt que l'état global.
Le principal piège est le couplage caché. Une fonction utilisant une variable globale dépend d'un état externe non visible dans sa signature, ce qui rend son comportement imprévisible. Cela complique les tests, augmente le temps de débogage et rend les refactorisations risquées.

Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

php variable globale variables globales php portée variables php global vs $globals php superglobales php
Autor Étienne Lambert
Étienne Lambert
Je m'appelle Étienne Lambert et j'ai 13 ans d'expérience dans le développement web, avec un accent particulier sur JavaScript, le backend, NoSQL et la sécurité. Mon parcours dans ce domaine a commencé par une curiosité insatiable pour la technologie et la manière dont elle façonne notre monde. J'aime partager mes connaissances et aider les lecteurs à naviguer dans les complexités du développement web, en rendant des sujets parfois ardus plus accessibles. Je m'efforce toujours de fournir des informations utiles, précises et à jour, en vérifiant mes sources et en comparant les différentes perspectives. J'écris sur des sujets variés qui vont des meilleures pratiques en matière de sécurité aux tendances émergentes dans le développement. Mon objectif est de simplifier des concepts techniques et d'organiser les connaissances de manière claire, afin que chacun puisse en tirer profit et se sentir confiant dans ses compétences en développement web.

Commentaires (0)

Ajouter un commentaire