POO en PHP (11) - Les namespaces (espaces de noms)

Dans cette leçon de programmation orientée objet en PHP, l’instructeur explique le problème des collisions de noms (fonctions, classes, constantes) dans de grands projets ou lorsqu’on utilise des bibliothèques tierces, puis introduit les namespaces comme solution. Il montre comment déclarer un namespace avec la syntaxe simple (ligne unique) ou à accolades, crée une classe personnalisée nommée PDO dans son propre namespace (MyMMS) et démontre que le code s’exécute sans conflit. Il explique ensuite comment accéder à la classe PDO native du cœur de PHP en préfixant le nom avec un antislash pour revenir à l’espace de noms global, et illustre cela avec une requête PDO sur une base de données de démonstration. Le formateur montre également l’utilisation de namespaces imbriqués (ns\myNMS), l’affichage du namespace courant via la constante __NAMESPACE, et rappelle que les namespaces s’appliquent aussi en code procédural. La vidéo se conclut par une invitation à consulter la documentation officielle de PHP.
Chapters
Bonjour à tous et bienvenue dans cette nouvelle leçon de programmation orientée objet en PHP. Aujourd'hui nous allons voir les espaces de noms ou namespaces. Avant d'entrer dans le vif du sujet, imaginons que vous voulez enregistrer un fichier nommé rapport.pdf sur votre bureau. Or, il existe déjà un fichier du même nom dans cet emplacement. Donc vous ne pourrez pas enregistrer votre fichier en tant que tel, car tout simplement, votre système ne vous le permettra pas afin d'éviter tout risque de conflit entre fichiers. Par conséquent, 2 solutions s'offrent à vous: soit vous renommez l'un des 2 fichiers afin que ces derniers aient des noms différents, ou créer un dossier dans lequel vous placez l'un des 2 fichiers tout en gardant le même nom. En réalité, ce genre de problème est omniprésent en programmation, en l'occurrence en PHP. En effet, on ne peut pas déclarer des constantes, des fonctions ou des classes du même nom dans le même document. Le compilateur soulèvera une erreur vous indiquant qu'une entité du même nom a déjà été déclarée. La gravité de l'erreur change selon le type de l'entité. Une notification sera soulevée en cas de duplication des constantes alors qu'une erreur fatale survient face à la détection de fonctions ou de classes du même nom. Vous vous dites probablement que vous ne risquez pas de tomber dans ce genre de problème car vous connaissez bien votre code et vous ne commettrez pas l'erreur de déclarer des fonctions ou des classes avec le même nom. Pour les petits projets, oui, c'est possible, mais quand vous avez affaire à de grandes applications qui renferment des dizaines de milliers de lignes de code, alors le risque est de taille. En fait, même face aux petits projets on peut se confronter à ce genre de problème si par hasard on y utilise des bibliothèques téléchargées. Vu que la plupart des développeurs ignorent le contenu de ces bibliothèques-là et s'intéressent principalement à comment s'en servir plutôt qu'à qu'est-ce qu'elles contiennent comme code, alors il est possible qu'on déclare une fonction ou une classe avec le même nom qu'une entité du même type qui a été déclarée dans la bibliothèque téléchargée. Bref, le risque est toujours présent. La solution face à ce genre de problème c'est d'utiliser des espaces de noms ou namespaces. Ces derniers sont des espaces virtuels que l'on crée dans notre code et qui jouent le même rôle que les dossiers dans votre bureau, ou votre système de fichiers en général, c'est-à-dire qu'ils encapsulent vos éléments dans des espaces différents. Dans ce cas, même si vous déclarez des entités du même nom, ça ne risque pas de compromettre votre code vu qu'ils sont placés dans des espaces à part. Notez que l'utilité des namespaces ne se manifeste pas qu'en programmation orientée objet, mais aussi quand on code en PHP dans son aspect procédural, sauf que ce concept est largement utilisé en POO. Imaginons que vous ignorez l'existence de la classe PDO et que par hasard vous avez créé une classe du même nom comme ceci. Dedans on va placer une méthode publique, d'ailleurs c'est une méthode qui figure au sein de la classe prédéfinie PDO. Cette méthode va nous afficher tout simplement le message il s'agit d'une classe personnalisée. Maintenant nous allons instancier cette classe, puis on va appeler la méthode Prepare. Exécutons. Le compilateur répond qu'on ne peut pas créer une classe du nom de PDO car cette classe est déjà présente. Et c'est tout à fait naturel puisqu'on ne peut pas utiliser des classes du même nom dans le même document. Donc si vous avez tellement progressé dans votre code et que ça sera difficile de procéder à toutes les modifications nécessaires, dans ce cas la solution la plus pertinente c'est de se servir des namespaces comme ceci. Avant la déclaration de la classe PDO, on va mettre la syntaxe suivante. Dans ce cas, je viens de créer un espace de noms du nom MyMMS, c'est-à-dire tout le code qui va suivre appartient à cet espace. La méthode avec laquelle j'ai déclaré cet espace de noms s'appelle la syntaxe à combinaison simple. Parce que sinon on peut utiliser la syntaxe à accolades comme ceci. Dans ce cas tout ce qui est placé entre les accolades appartient à cet espace de noms, mais je préfère largement la syntaxe à combinaison simple. Réexécutons. On voit bien que le code s'est exécuté correctement et la méthode Prepare a affiché le message il s'agit d'une classe personnalisée. Alors on constate qu'il n'y a pas de conflit entre la classe prédéfinie PDO et la classe personnalisée que je viens de créer avec le même nom. Maintenant imaginez que je veux utiliser la classe PDO prédéfinie. Comme ça par exemple, je vais mettre un séparateur avec la balise HR et je vais déclarer la chaîne de connexion PDO. Comme ceci. Je vais préparer une requête. Cette requête va tout simplement me retourner les noms des tables qui sont déclarées dans la base de données tuto-php. Après avoir exécuté la requête, on va récupérer le jeu de données. Puis on va afficher le résultat. Comme ceci. Alors exécutons. On voit bien que nous avons des erreurs et c'est normal parce que n'oubliez pas que je suis toujours dans le même espace de noms myNMS. Dans ce cas, la classe PDO que je viens d'instancier ici, ce n'est pas la classe PDO que l'on connaît, mais c'est la classe que j'ai créée, la classe personnalisée. Puisque tout le code qui est sur cette page appartient à l'espace de noms myNMS. Alors pour dire au compilateur PHP que je veux instancier la classe PDO d'origine, je dois me rendre dans ce que l'on appelle l'espace de noms global. C'est cet espace qui contient tous les éléments prédéfinis du PHP. Pour accéder à cet espace de noms global, on va faire exactement comme on le fait sur un système d'exploitation, en l'occurrence sur Windows. On mettra juste un antislash pour dire que je me rends à la racine. C'est exactement comme c'est le cas dans un système de fichiers, on met slash ou bien antislash pour se rendre à la racine. Dans ce cas, l'anti-slash fait référence à l'espace de noms global et la classe PDO qui sera appelée dans ce cas, c'est la classe PDO reconnue par défaut par le compilateur PHP. Exécutons. Alors on voit bien que notre code marche. Dans la première partie, c'est la classe PDO personnalisée. Dans la deuxième partie, c'est la classe PDO par défaut. Imaginez que je veux faire appel à la méthode setFetchMode afin de solliciter un tableau associatif au moment de la récupération du jeu de données. Si je ne fais que ça, dans ce cas PDO qui est là fait référence à la classe PDO qui est définie dans l'espace de noms MyNms. Là encore, il faut se rendre dans l'espace global pour dire c'est la classe PDO par défaut. Et puisque c'est un tableau associatif, donc ça devrait pas marcher ici. Alors je vais modifier légèrement ce code. Bon, ça convertit le tableau tab en une chaîne de caractères, sachant que chaque ligne du tableau tab ne contient qu'une seule valeur qui est le nom de chacune des tables qui figurent dans la base de données. Réexécutons. Alors on constate que ça marche toujours de la même manière. Bien sûr, on peut gérer les espaces de noms de la même manière que l'on fait pour les dossiers dans un système de fichiers. Au lieu de myNMS, je vais mettre par exemple ns\myNMS. C'est un peu comme si nous avons créé un dossier qui s'appelle ns et dedans un sous-dossier qui s'appelle myNMS. Alors tout le code qui est là appartient à l'espace de nom ns\myNMS. Réexécutons. Aucun changement. Notez que si vous avez affaire à plusieurs espaces de noms dans le même document, dans ce cas il se peut qu'on soit confondu et qu'on ne sait pas dans quel espace on est en train de travailler. Heureusement, une constante prédéfinie est prévue pour ça. On va mettre echo, la constante s'appelle namespace, elle est mise entre deux doubles sous-tirets comme ça. Voilà, on va voir maintenant dans quel espace de noms on est en train de travailler. Et ça m'affiche ns/myNms. Là encore je mettrai un trait. Voilà, comme ça. Donc je crois que vous avez compris l'utilité des namespaces en PHP. Il permet d'encapsuler les différents éléments de votre code dans des espaces de noms différents afin d'éviter tout conflit ou bien toute collision. Je vous invite quand même à vous rendre sur le support officiel de PHP sur le site www.php.net afin de vous renseigner davantage sur l'utilisation des espaces de noms. Merci pour votre attention et à la vidéo prochaine.
More from Yamossoun

Algorithme de calcule de la racine carrée par dichotomie #dichotomy #squareroot #algorithm









