Una interfaz de PHP declara los métodos que una clase promete ofrecer, sin ningún código: interface Shape { public function area(): float; }. Una clase que escribe implements Shape debe definir area(), y cualquier función con la declaración de tipo Shape aceptará esa clase.
A describe() no le importa qué clase recibe. Solo depende de la promesa que hace la interfaz, así que un nuevo Triangle implements Shape funciona con ella sin cambiar una línea.
Programar contra una interfaz
El motivo habitual para escribir una interfaz es que el código dependa de una capacidad y no de una clase concreta. Aquí un servicio de pedidos acepta cualquier Notifier, así que el mismo código puede enviar emails en producción y reunir los mensajes en un test:
Implementar varias interfaces
Una clase extiende como mucho un padre, pero puede implementar tantas interfaces como necesite. Enuméralas después de implements, separadas por comas, y define los métodos de todas ellas:
JsonSerializable es una de las interfaces nativas de PHP: implementarla controla lo que produce json_encode() para el objeto.
Constantes de interfaz
Una interfaz puede declarar constantes. Todas las clases que la implementan las heredan, y puedes leerlas a través del nombre de la interfaz o del de la clase:
En PHP 8.3 las interfaces no pueden tener propiedades, solo métodos y constantes. Los métodos pueden ser estáticos: public static function fromArray(array $data): static; en la interfaz obliga a cada clase a definir ese método estático. Para un conjunto fijo de valores relacionados, un enum suele encajar mejor que una lista de constantes de interfaz.
Una interfaz puede extender otras interfaces
Las interfaces también usan extends y, a diferencia de las clases, pueden extender varias a la vez. Una clase que implementa la interfaz hija debe definir los métodos de toda la cadena:
Interfaces nativas: Countable, IteratorAggregate, Stringable
PHP trae interfaces que conectan los objetos con el lenguaje. Countable hace que funcione count($obj), IteratorAggregate hace que funcione foreach, y Stringable la implementa automáticamente cualquier clase con un método __toString():
Olvidar un método
Si una clase dice implementar una interfaz pero le falta un método, PHP se detiene con un error fatal que nombra el método que falta:
Añade un método total() y el script funciona. Una clase abstracta puede dejar sin definir métodos de la interfaz, que es la salida que sugiere el mensaje de error.
Interfaz vs clase abstracta
Las dos definen métodos que una clase debe tener, y las dos se pueden usar como declaración de tipo. La diferencia está en qué más pueden contener y cuántas puede usar una clase:
| Interfaz | Clase abstracta | |
|---|---|---|
| Cuerpo de los métodos | ninguno (solo firmas) | métodos abstractos y terminados |
| Propiedades | no | sí |
| Constructor | puede declarar uno, rara vez útil | sí, con código |
| Visibilidad de los métodos | solo public | public, protected, private |
| Constantes | sí | sí |
| Cuántas por clase | cualquier número (implements A, B, C) | una (extends Base) |
| Uso típico | una capacidad: Exportable, Countable | código compartido de una familia: Model, Controller |
Se combinan bien: define la interfaz para la declaración de tipo y ofrece una clase base abstracta que la implemente con el código común. Las clases que necesiten otra base pueden seguir implementando la interfaz directamente.
Preguntas frecuentes
¿Qué es una interfaz en PHP?
Una lista de firmas de métodos públicos sin cuerpo: interface Logger { public function log(string $msg): void; }. Una clase que declara implements Logger debe definir todos sus métodos, y cualquier código con la declaración de tipo Logger acepta esa clase.
¿Una clase de PHP puede implementar varias interfaces?
Sí. Enuméralas después de implements, separadas por comas: class File implements Readable, Writable, Countable. La clase debe definir los métodos de todas ellas. Así cubre PHP lo que la herencia múltiple hace en otros lenguajes.
¿Cuál es la diferencia entre una interfaz y una clase abstracta en PHP?
Una interfaz solo declara métodos públicos (y constantes); no tiene propiedades ni código en los métodos, y una clase puede implementar muchas. Una clase abstracta puede contener propiedades, constructores y métodos terminados junto a los abstractos, pero una clase solo puede extender una. Usa una interfaz para una capacidad ("se puede exportar") y una clase abstracta para código compartido en una familia de clases.
¿Una interfaz de PHP puede tener propiedades?
No en PHP 8.3: una interfaz puede contener firmas de métodos y constantes (const VERSION = 2;), pero no propiedades. Las declaraciones de propiedades en interfaces (property hooks) solo llegaron en PHP 8.4.
¿Cómo compruebo si un objeto implementa una interfaz en PHP?
Usa instanceof: $obj instanceof Countable es verdadero cuando la clase del objeto implementa la interfaz, directamente o a través de una clase padre. class_implements($obj) devuelve los nombres de todas las interfaces que implementa la clase.