An interface defines a contract — a set of method signatures that implementing classes must provide. Unlike abstract classes, interfaces contain no implementation and no state.
Declare with interface InterfaceName.
Implement with class Foo implements InterfaceA, InterfaceB — a class can implement multiple interfaces.
All interface methods are implicitly public abstract.
Interfaces can define const values and, since PHP 8.0, can extend multiple interfaces.
Example
<?php
interface Renderable
{
public function render(): string;
}
interface Cacheable
{
public function getCacheKey(): string;
public function getTtl(): int;
}
interface Loggable
{
public function getLogContext(): array;
}
// A class can implement multiple interfaces
class HtmlWidget implements Renderable, Cacheable, Loggable
{
public function __construct(
private string $id,
private string $content
) {}
public function render(): string
{
return "<div id=\"{$this->id}\">{$this->content}</div>";
}
public function getCacheKey(): string
{
return "widget:{$this->id}";
}
public function getTtl(): int { return 3600; }
public function getLogContext(): array
{
return ['widget_id' => $this->id, 'type' => static::class];
}
}
// Type-hint against the interface, not the concrete class
function renderAll(Renderable ...$items): string
{
return implode("
", array_map(fn($i) => $i->render(), $items));
}
$widget = new HtmlWidget('hero', 'Welcome!');
echo $widget->render();
echo ($widget instanceof Renderable) ? 'Renderable' : '';
echo ($widget instanceof Cacheable) ? 'Cacheable' : '';
Pro Tip
Tip: Program to interfaces, not implementations. When you type-hint Renderable instead of HtmlWidget, your function can accept any renderable object — making code loosely coupled and easy to unit-test with mock objects.