# Types d’intersection PHP 8.1 : contraindre un paramètre à deux interfaces

> Comment exiger qu'un objet remplisse deux contrats à la fois, sans créer une interface intermédiaire artificielle ? PHP 8.1 propose une réponse directe au typage.

- Auteur : Clément Hadrot
- Publié le : 2026-02-01
- Mis à jour le : 2026-02-01
- Catégorie : Astuces
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/types-intersection-php81-contraindre-deux-interfaces/

## L’essentiel

- Exige qu'un objet implémente plusieurs interfaces à la fois
- Évite de créer une interface intermédiaire artificielle
- Fonctionnalité distincte des types union de PHP 8.0

Comment exiger, dans la signature d'une fonction, qu'un objet remplisse deux contrats à la fois — être à la fois `Countable` et `ArrayAccess`, par exemple — sans se contenter d'un type générique `object` qui perdrait toute garantie ? Avant PHP 8.1, la réponse habituelle consistait à créer une interface intermédiaire qui hérite des deux, uniquement pour ce besoin de typage. PHP 8.1 introduit une solution plus directe : les types d'intersection.

Cette fonctionnalité répond à un besoin différent des types union apparus avec PHP 8.0 : là où un type union autorise l'une ou l'autre des interfaces indiquées, un type d'intersection exige la conformité aux deux simultanément.

## La syntaxe et sa signification

Un type d'intersection s'écrit avec le symbole `&` entre deux noms de types, par exemple `Countable&ArrayAccess`. PHP vérifiera, à l'exécution, que l'objet passé implémente bien les deux interfaces mentionnées — pas une combinaison de classes concrètes, cette syntaxe étant réservée aux interfaces et aux classes abstraites, jamais aux types scalaires comme `int` ou `string`.

Cette fonctionnalité s'avère particulièrement utile dans la conception d'une API interne d'extension, quand un composant doit accepter un objet qui se comporte à la fois comme une collection dénombrable et comme un tableau accessible par clé, sans imposer une classe concrète précise à l'appelant.

## Un exemple : une API interne d'extension

> L'essentiel à retenir : Exige qu'un objet implémente plusieurs interfaces à la fois ; Évite de créer une interface intermédiaire artificielle ; Fonctionnalité distincte des types union de PHP 8.0

Imaginons une extension de gestion de panier qui définit deux interfaces distinctes, l'une pour le comptage, l'autre pour l'accès par clé, et une méthode qui exige les deux à la fois :

```
interface PanierDenombrable {
    public function compterArticles(): int;
}

interface PanierAccessibleParCle {
    public function obtenirArticle( string $cle );
}

class GestionnairePanier {
    public function afficherResume( PanierDenombrable&PanierAccessibleParCle $panier ): string {
        $nombre = $panier->compterArticles();

        return sprintf(
            /* translators: %d : nombre d'articles dans le panier */
            __( '%d article(s) dans le panier', 'boutique-interne' ),
            $nombre
        );
    }
}
```

N'importe quelle classe implémentant à la fois `PanierDenombrable` et `PanierAccessibleParCle` peut être passée à `afficherResume()`, sans qu'il soit nécessaire de créer une troisième interface, `PanierComplet`, qui hériterait des deux uniquement pour satisfaire la signature de cette méthode.

## Ce que les types d'intersection ne remplacent pas

- Ils ne remplacent pas les types union, introduits par PHP 8.0, qui répondent à un besoin inverse : accepter l'un ou l'autre type, pas les deux ensemble.
- Ils ne peuvent pas mélanger un type d'intersection et un type union dans une même déclaration en PHP 8.1 : cette combinaison, appelée type disjonctif normal, n'arrivera qu'avec PHP 8.2.
- Ils ne s'appliquent qu'aux interfaces et classes, jamais aux types scalaires ni au type `null`, qui ne peut pas être combiné dans une intersection.

## Quand préférer une interface unique classique

Les types d'intersection ne doivent pas devenir un réflexe systématique. Si deux interfaces sont presque toujours utilisées ensemble dans l'ensemble du projet, il reste souvent plus lisible de définir une véritable interface combinée, avec un nom métier clair, plutôt que de répéter `InterfaceA&InterfaceB` dans chaque signature de méthode concernée. Le type d'intersection convient mieux à un besoin ponctuel, localisé à une ou deux méthodes.

> Réserver les types d'intersection aux combinaisons ponctuelles : si la même paire d'interfaces revient dans toute l'API d'une extension, une interface combinée nommée reste plus lisible qu'une répétition du type d'intersection partout.

## Compatibilité à vérifier

Comme pour toute syntaxe apparue avec PHP 8.1, cette fonctionnalité impose un minimum de version PHP 8.1 sur l'hébergement ciblé. Une extension qui viserait encore une compatibilité avec PHP 8.0 ou une version antérieure ne peut pas utiliser cette syntaxe, et devra se contenter d'une interface intermédiaire classique ou d'une vérification via `instanceof` dans le corps de la méthode.

## En résumé

Les types d'intersection de PHP 8.1 répondent à un besoin de conception précis : exiger qu'un paramètre remplisse plusieurs contrats à la fois, sans passer par une interface intermédiaire créée uniquement pour cet usage. Ils complètent, sans les remplacer, les types union apparus l'année précédente, et trouvent leur place dans la conception d'API internes d'extension où deux comportements doivent cohabiter sur un même objet.
