Une interface PHP déclare des méthodes qu'une classe promet de fournir, sans aucun code : interface Shape { public function area(): float; }. Une classe qui écrit implements Shape doit définir area(), et toute fonction qui type un paramètre avec Shape acceptera cette classe.
describe() ne sait pas, et ne se soucie pas de savoir, quelle classe elle reçoit. Elle ne compte que sur la promesse de l'interface, donc un nouveau Triangle implements Shape fonctionne avec elle sans changer une ligne.
Programmer pour une interface
La raison habituelle d'écrire une interface est de faire dépendre le code d'une capacité plutôt que d'une classe précise. Ici, un service de commandes accepte n'importe quel Notifier, donc le même code peut envoyer des emails en production et collecter les messages dans un test :
Implémenter plusieurs interfaces
Une classe étend au plus un parent, mais elle peut implémenter autant d'interfaces que nécessaire. Listez-les après implements, séparées par des virgules, et définissez les méthodes de toutes :
JsonSerializable est l'une des interfaces natives de PHP : l'implémenter contrôle ce que produit json_encode() pour l'objet.
Constantes d'interface
Une interface peut déclarer des constantes. Chaque classe qui l'implémente en hérite, et vous pouvez les lire via le nom de l'interface ou celui de la classe :
Les interfaces ne peuvent pas avoir de propriétés en PHP 8.3, seulement des méthodes et des constantes. Les méthodes peuvent être statiques : public static function fromArray(array $data): static; dans l'interface oblige chaque classe à définir cette méthode statique. Pour un ensemble fixe de valeurs liées, une enum convient souvent mieux qu'une liste de constantes d'interface.
Une interface peut en étendre d'autres
Les interfaces utilisent aussi extends, et contrairement aux classes elles peuvent en étendre plusieurs à la fois. Une classe qui implémente l'interface enfant doit définir les méthodes de toute la chaîne :
Interfaces natives : Countable, IteratorAggregate, Stringable
PHP fournit des interfaces qui relient les objets au langage. Countable fait fonctionner count($obj), IteratorAggregate fait fonctionner foreach, et Stringable est implémentée automatiquement par toute classe ayant une méthode __toString() :
Oublier une méthode
Si une classe affirme implémenter une interface mais oublie une méthode, PHP s'arrête avec une erreur fatale qui nomme la méthode manquante :
Ajoutez une méthode total() et le script s'exécute. Une classe abstraite peut laisser des méthodes d'interface non définies, c'est l'échappatoire que suggère le message d'erreur.
Interface ou classe abstraite
Les deux définissent des méthodes qu'une classe doit avoir, et les deux peuvent servir de type. La différence tient à ce qu'elles peuvent contenir d'autre et au nombre qu'une classe peut utiliser :
| Interface | Classe abstraite | |
|---|---|---|
| Corps de méthodes | aucun (seulement des signatures) | méthodes abstraites et terminées |
| Propriétés | non | oui |
| Constructeur | peut en déclarer un, rarement utile | oui, avec du code |
| Visibilité des méthodes | public seulement | public, protected, private |
| Constantes | oui | oui |
| Combien par classe | autant que voulu (implements A, B, C) | une (extends Base) |
| Usage typique | une capacité : Exportable, Countable | du code partagé dans une famille : Model, Controller |
Elles se combinent bien : définissez l'interface pour le typage, et proposez une classe de base abstraite qui l'implémente avec le code commun. Les classes qui ont besoin d'une autre base peuvent toujours implémenter directement l'interface.
Questions fréquentes
Qu'est-ce qu'une interface en PHP ?
Une liste de signatures de méthodes publiques sans corps : interface Logger { public function log(string $msg): void; }. Une classe qui déclare implements Logger doit définir chacune de ces méthodes, et tout code qui type un paramètre avec Logger accepte cette classe.
Une classe PHP peut-elle implémenter plusieurs interfaces ?
Oui. Listez-les après implements, séparées par des virgules : class File implements Readable, Writable, Countable. La classe doit définir les méthodes de toutes. C'est ainsi que PHP couvre ce que fait l'héritage multiple dans d'autres langages.
Quelle est la différence entre une interface et une classe abstraite en PHP ?
Une interface ne déclare que des méthodes publiques (et des constantes) ; elle n'a ni propriétés ni code de méthode, et une classe peut en implémenter plusieurs. Une classe abstraite peut contenir des propriétés, des constructeurs et des méthodes terminées à côté de ses méthodes abstraites, mais une classe ne peut en étendre qu'une. Utilisez une interface pour une capacité (« peut être exporté »), une classe abstraite pour du code partagé dans une famille de classes.
Une interface PHP peut-elle avoir des propriétés ?
Pas en PHP 8.3 : une interface peut contenir des signatures de méthodes et des constantes (const VERSION = 2;), mais pas de propriétés. Les déclarations de propriétés dans les interfaces (property hooks) ne sont arrivées qu'en PHP 8.4.
Comment vérifier si un objet implémente une interface en PHP ?
Utilisez instanceof : $obj instanceof Countable est vrai quand la classe de l'objet implémente l'interface, directement ou via une classe parente. class_implements($obj) renvoie les noms de toutes les interfaces qu'implémente la classe.