Interfejs może być własnym typem, oznaczającym obiekt dowolnej klasy implementującej dany interfejs. Poznajmy tę sztuczkę programowania obiektowego!

Oto interfejs i dwie klasy implementujące go:

<?php

declare(strict_types=1);

interface RuleInterface
{
  public function validate(array $data, string $field, array $params): bool;

  public function getMessage(): string;
}

class UrlRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    return (bool) filter_var($data[$field], FILTER_VALIDATE_URL);
  }

  public function getMessage(): string
  {
    return "Invalid URL";
  }
}

class EmailRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    return (bool) filter_var($data[$field], FILTER_VALIDATE_EMAIL);
  }

  public function getMessage(): string
  {
    return "Invalid email";
  }
}

Piszemy funkcję, która przyjmie obiekt dowolnej klasy i wyświetli jego metodę getMessage:

<?php

declare(strict_types=1);

interface RuleInterface
{
 //(...)
}

class UrlRule implements RuleInterface
{
  //(...)
}

class EmailRule implements RuleInterface
{
  //(...)
}

function message(UrlRule|EmailRule $rule) {
    echo $rule->getMessage();
}

$emailRule = new EmailRule();
$urlRule = new UrlRule();
message($emailRule);
message($urlRule);

Użyliśmy typu „unijnego” pozwalając na przekazanie obiektu typu UrlRule albo EmailRule. Nie jest to bardzo praktyczne.

Zamiast tego, możemy użyć jako typ nazwę interfejsu:

<?php

declare(strict_types=1);

interface RuleInterface
{
 //(...)
}

class UrlRule implements RuleInterface
{
  //(...)
}

class EmailRule implements RuleInterface
{
  //(...)
}

function message(RuleInterface $rule) {
    echo $rule->getMessage();
}

$emailRule = new EmailRule();
$urlRule = new UrlRule();
message($emailRule);
message($urlRule);

Teraz nasza funkcja może przyjąć dowolny obiekt, pod warunkiem, że jest to obiekt klasy implementującej interfejs RuleInterface.

Używanie interfejsów jako typów strasznie ułatwia pisanie obiektowego kodu.