DevTips – Espaces de noms en PHP

Publié: 2020-03-06

Il y a environ un an, WordPress a décidé de mettre à jour la version PHP minimale requise, de 5.2 (utilisée depuis 2010) à quelque chose de plus à jour. En effet, aujourd'hui la version minimale de PHP recommandée par WordPress est l'une des plus récentes : PHP 7.3.

Si vous êtes un simple utilisateur de WordPress, cela ne vous impactera probablement pas trop (au-delà du fait que ces nouvelles versions donnent de meilleures performances).

Mais si vous êtes un développeur, ces nouvelles versions de PHP ont des fonctionnalités impressionnantes que vous pouvez utiliser dans vos plugins et thèmes. Et aujourd'hui, plus précisément, je voudrais vous parler d'un qui nous accompagne depuis longtemps mais : les espaces de noms.

WordPress et préfixes de code

L'une des premières règles que vous apprenez en tant que développeur WordPress est "d'utiliser des préfixes dans tout ce que nous faisons" pour éviter les "collisions de noms". Comme on peut le lire dans les bonnes pratiques de WordPress :

Une collision de noms se produit lorsque votre plugin utilise le même nom pour une variable, une fonction ou une classe qu'un autre plugin.

[Pour éviter les collisions de noms], toutes les variables, fonctions et classes doivent être précédées d'un identifiant unique. Les préfixes empêchent d'autres plugins d'écraser vos variables et d'appeler accidentellement vos fonctions et classes. Cela vous empêchera également de faire la même chose.

Meilleures pratiques pour développer des plugins WordPress

Ainsi, par exemple, au lieu de créer une fonction comme get_site_id , il vaut mieux la nommer nelio_content_get_site_id . De cette façon, nous sommes en mesure d'identifier rapidement le plugin ( nelio_content ) ou le thème auquel appartient une certaine fonction ( get_site_id ) et d'éviter des erreurs fatales si plusieurs plugins tentent de définir la même fonction.

L'utilisation de préfixes est une manière rudimentaire de créer un « espace de noms » ; une solution de contournement que nous avons dû mettre en œuvre lorsque nous n'avions pas de meilleure alternative. Tous ces éléments qui utilisent le même préfixe font partie du même ensemble ou espace de noms. Mais cela se traduit par un code inutilement plus complexe : les noms sont plus longs à cause des préfixes qui ne servent à rien d'autre qu'émuler des espaces de noms.

Espaces de noms PHP

La version 5.3 de PHP a introduit le concept d'espace de noms . La définition qu'ils en donnent dans la documentation me semble excellente, je la reproduis donc ici :

Dans la définition la plus large, les espaces de noms sont un moyen d'encapsuler des éléments. Cela peut être considéré comme un concept abstrait dans de nombreux endroits. Par exemple, dans n'importe quel système d'exploitation, les répertoires servent à regrouper les fichiers associés et agissent comme un espace de noms pour les fichiers qu'ils contiennent. Comme exemple concret, le fichier foo.txt peut exister à la fois dans le répertoire /home/greg et dans /home/other , mais deux copies de foo.txt ne peuvent pas coexister dans le même répertoire.

Dans le monde PHP, les espaces de noms sont conçus pour résoudre deux problèmes rencontrés par les auteurs de bibliothèques et d'applications lors de la création d'éléments de code réutilisables tels que des classes ou des fonctions :

1. Nommez les collisions entre le code que vous créez et le code PHP interne ou le code tiers.

2. Possibilité d'alias (ou de raccourcir) Extra_Long_Names , améliorant la lisibilité du code source.

Documentation PHP

Comment créer un espace de noms

Créer un espace de noms en PHP est extrêmement simple. Au début du fichier PHP que vous créez, ajoutez une directive d' namespace de noms avec le nom que vous souhaitez utiliser et « tout » que vous définissez dans ce fichier appartiendra à cet espace de noms :

 <?php namespace Nelio_Content;

Oui, c'est aussi simple que ça ! Maintenant, "tout" que nous y créons sera dans l'espace de noms Nelio_Content . Par exemple, si je définis une fonction comme celle que j'ai mentionnée au début :

 <?php namespace Nelio_Content; function get_site_id() { // ... }

nous savons maintenant que get_site_id est à l'intérieur de l'espace de noms Nelio_Content . De cette façon, nous n'avons plus besoin d'utiliser le préfixe nelio_content_ lors de la définition de la fonction. Génial!

Exceptions aux espaces de noms

Si vous regardez attentivement ce que je vous ai dit jusqu'à présent, vous verrez que j'ai écrit "tout" entre guillemets : ""tout" que nous y ajouterons appartiendra à l'espace de noms spécifié." Pourquoi ai-je fait ça ? Parce que les espaces de noms ne s'appliquent pas à absolument tout le code que nous écrivons… il y a quelques exceptions.

Les espaces de noms PHP ne couvrent que les éléments PHP suivants :

  • Des classes
  • Interfaces
  • Traits
  • Les fonctions
  • Constantes déclarées avec const mais pas avec define

De plus, il y a des choses supplémentaires dans WordPress qui ont également besoin de leurs propres espaces de noms et, malheureusement, les espaces de noms PHP ne couvrent pas : vos poignées de script, les options de base de données ou les types de contenu personnalisés et leurs métadonnées, etc. Dans tous ces cas, vous devez continuer à utiliser les préfixes.

Comment importer des éléments d'un espace de noms à un autre

Si vous avez besoin d'utiliser un élément qui se trouve dans votre propre espace de noms, vous n'avez rien à faire de spécial : appelez-le simplement par son nom. Par exemple, dans l'extrait de code suivant :

 <?php namespace Nelio_Content; function get_site_id() { // ... } function get_auth_token() { $site_id = get_site_id(); // ... }

Vous pouvez voir que nous avons défini deux fonctions : get_site_id et get_auth_token , toutes deux dans l'espace de noms Nelio_Content . Lorsque get_auth_token doit utiliser get_site_id , il l'appelle simplement comme d'habitude.

Si, en revanche, vous devez utiliser get_site_id dans un espace de noms différent, vous devez appeler la fonction en utilisant son identifiant complet :

 <?php namespace Something_Else; function do_some_action() { $site_id = Nelio_Content\get_site_id(); // ... }

ou vous devez importer la fonction avec le mot clé use :

 <?php namespace Something_Else; use Nelio_Content\get_site_id; function do_some_action() { $site_id = get_site_id(); // ... }

Personnellement, j'aime beaucoup la deuxième option : en utilisant le mot-clé use pour importer des fonctions d'autres espaces de noms, vous pouvez jeter un coup d'œil rapide à l'en-tête de votre fichier et identifier ses dépendances.

Filtres et actions WordPress avec les espaces de noms PHP

Il y a un détail important que vous devez garder à l'esprit lorsque vous utilisez des espaces de noms à côté des filtres et des actions WordPress. Lorsque vous spécifiez des rappels de filtre et d'action, vous le faites généralement en donnant le nom du rappel sous forme de chaîne :

 <?php // ... add_action( 'init', 'do_some_action' );

Le problème est que si cette fonction se trouve dans un espace de noms, le crochet précédent ne fonctionnera pas comme prévu ; vous devez indiquer à WordPress le nom complet de la fonction. En d'autres termes, vous devez inclure son espace de noms (s'il en a un).

Ajoutez-vous le crochet dans le fichier où vous définissez l'espace de noms lui-même ? Peu importe, utilisez le nom complet :

 <?php namespace Nelio_Content; function do_some_action() { // ... } add_action( 'init', 'Nelio_Content\do_some_action' );

Êtes-vous dans un autre espace de noms mais avez-vous importé la fonction avec use ? Peu importe non plus, utilisez le nom complet :

 <?php namespace Something_Else; use Nelio_Content\do_some_action; // ... add_action( 'init', 'Nelio_Content\do_some_action' );

Utiliser des alias avec nos espaces de noms

Une autre fonctionnalité très intéressante des espaces de noms est l'aliasing. Imaginez le scénario suivant :

 <?php namespace Nelio_Content; function get_site_id() { // ... }

Si je veux utiliser cette fonction dans un autre espace de noms, nous avons déjà vu que je peux le faire avec use . Mais comment utiliser cette fonction si le module dans lequel je veux l'utiliser a déjà une fonction appelée get_site_id ?

Eh bien, heureusement pour moi, nous pouvons associer nos importations à de nouveaux noms :

 <?php namespace Something_Else; use Nelio_Content\get_site_id as get_nc_site_id(); function get_site_id() { // ... } function do_some_action() { $nc_site_idd = get_nc_site_id(); // ... }

Commencez à utiliser les espaces de noms dès aujourd'hui !

Les espaces de noms sont un outil fantastique pour éviter les collisions de noms et pour organiser notre code. En fait, et bien que je n'aie pas commenté cet article, il existe des normes telles que PSR-4 qui permettent à PHP de charger automatiquement des classes en fonction de la structure des espaces de noms que vous utilisez et de la manière dont vous organisez le code en répertoires et fichiers.

Si vous n'utilisez pas encore d'espaces de noms dans vos projets, nous vous recommandons de commencer à le faire dès maintenant. Parlez-nous de votre expérience dans les commentaires !

Image sélectionnée par Chaitanya Tvs sur Unsplash.