Apprendre PHP & MySQL : Namespaces

Les namespaces en PHP sont une fonctionnalité essentielle pour organiser et structurer proprement votre code.

Icône de calendrier
Intermédiaire
12 chapitres

Pourquoi utiliser des namespaces ?

Problématique : conflit de noms

Pour bien comprendre les namespaces, décrivons un scénario problématique.

Supposons que vous développiez un site web e-commerce. Pour votre système de commandes, vous décidez de créer une classe Order afin de gérer les commandes :

Order.php
copié !
class Order {
	// ...
}

Plus tard, vous décidez d’intégrer une bibliothèque tierce de traitement des paiements, comme Stripe, qui a également une classe nommée Order pour gérer les commandes lors des transactions.

Et là, on fonce droit dans le mur :

copié !
// Intégration de ma classe Order
require('my-classes/Order.php');
// Intégration de la classe Order de la bibliothèque Stripe
require('libs/stripe/Order.php'); // ⚠️ Erreur... PHP vous indique que la classe Order a déjà été déclarée

$order = new Order(); 

On obtient l’erreur suivante :

Fatal error: Cannot declare class Order, because the name is already in use in C:\wamp64\www\...\libs\stripe\Order.php

Qu’est-ce qu’un namespace ?

Les namespaces sont une fonctionnalité puissante pour organiser et structurer votre code PHP.

Ils permettent d’éviter les conflits de noms de classes, de fonctions et de constantes, en les regroupant dans des espaces de noms distincts.

Il s’agit de sortes de répertoires virtuels dans lesquels on range notre code.

Pour reprendre l’exemple précédent, les namespaces vont nous permettre de dire :

Charge MA classe Order Charge la classe Order de Stripe

Les namespaces facilitent ainsi :

  • La réutilisation du code
  • La collaboration entre développeurs
  • La gestion de bibliothèques externes

Ils sont particulièrement utiles dans les projets PHP de taille importante avec une dimension Orientée Objet ou lorsque vous travaillez avec des bibliothèques tierces.

En ce sens, il est important de comprendre le concept de namespace avant d’apprendre son premier framework PHP.

Namespaces, en pratique

Déclarer un namespace

Pour déclarer un namespace dans PHP, on utilise le mot-clé namespace. Notez à la suite le nom souhaité pour votre namespace.

Vous remarquez que la convention de nommage pour les namespaces consiste à utiliser la PascalCase.

Si vous souhaitez que votre namespace ait plusieurs niveaux de profondeur, vous pouvez utiliser le caractère \.

copié !
namespace Mon\Namespace;

Ce code définit un namespace nommé MonNamespace. Les classes, fonctions et constantes déclarées dans ce fichier appartiennent désormais à ce namespace.

Utiliser un namespace

Pour utiliser une classe (ou une fonction/constante d’un namespace), vous pouvez :

  1. Écrire le nom complet à chaque utilisation
  2. Importer le nom complet en haut du fichier

Ecriture du nom complet :

copié !
$maClasse = new Mon\Namespace\MaClasse();

Importation du nom complet :

copié !
use Mon\Namespace\MaClasse;

$maClasse = new MaClasse();

L’importation facilite l’utilisation des classes du namespace sans avoir à spécifier le nom complet à chaque fois. Cela s’avère très utile, voire indispensable, lorsque la classe est utilisée à de multiples reprises.

Reprenons l'exemple de nos deux classes Order, chacune étant dorénavant située dans son propre namespace
my-classes/Order.php
copié !
<?php
namespace MyClasses;

class Order {

}
my-classes/Order.php
copié !
<?php
namespace Libs\Stripe;

class Order {

}
copié !
require('my-classes/Order.php');
require('libs/stripe/Order.php'); // ✅ Les 2 namespaces sont différents : aucune erreur de redéclaration de classe

use Libs\Stripe\Order;

// ✅ PHP sait que la classe Order instanciée ici est celle de Stripe
$order = new Order();

Alias de namespace

Un alias consiste à donner un nom alternatif ou raccourci à un élément situé dans un namespace (comme une classe, une fonction, ou une variable).

Cela permet principalement d’en faciliter l’utilisation et d’éviter des conflits de noms.

Pour éviter les conflits

Si deux classes portant le même nom sont utilisées dans un même fichier, la seule solution pour les différencier et d’utiliser le nom complet.

copié !
require('my-classes/Order.php');
require('libs/stripe/Order.php');

// ✅ OK (classe identifiée par le nom complet)
$order = new Libs\Stripe\Order();

Si nous essayons d’importer la classe comme ceci :

copié !
require('my-classes/Order.php');
require('libs/stripe/Order.php');

use MyClasses\Order;
use Libs\Stripe\Order;

// ⚠️ Erreur... PHP vous indique que le terme "Order" a déjà été déclaré, il ne sait donc pas quelle classe instancier
$order = new Order();

On obtient l’erreur suivante :

Fatal error: Cannot use Libs\Stripe\Order as Order because the name is already in use in C:\wamp64\www\...\index.php

Si vous souhaitez quand même importer le namespace, alors la solution tient en un mot : l’alias.

copié !
require('my-classes/Order.php');
require('libs/stripe/Order.php');

use MyClasses\Order as MyOrder;
use Libs\Stripe\Order as StripeOrder;

// ✅ OK (classe identifiée par l'alias)
$order = new MyOrder();

Pour renommer une classe

Aussi, les alias de namespaces vous permettent de donner des noms plus courts et plus explicites à des classes (souvent issues de bibliothèques, des classes pour lesquelles vous n’avez pas choisi les noms).

Les alias de namespaces rendent ainsi votre code plus lisible.

copié !
require('libs/orm/MyCustomQueryBuilder.php');

use Libs\ORM\MyCustomQueryBuilder as QueryBuilder;

// ✅ OK (classe identifiée par l'alias)
$order = new QueryBuilder();