Multiple Interfaces

Multiple Interfaces and Interface Constants

A class has one parent but may implement any number of interfaces, and an interface may extends several others, which builds a large contract from small ones. Interfaces may carry constants, read through the interface or any implementing class. Since PHP 8.1 a class may override an inherited interface constant unless it is final; since 8.3 constants can be typed (Typed Class Constants).

A paperback and an e-book assembled from small interfacesPHP
<?php
interface HasSku { final public const string PREFIX = 'BK-'; public function sku(): string; }
interface Taxable { public const int TAX = 6; public function price(): int; }
interface Sellable extends HasSku, Taxable {}                 // combines two contracts
interface Shippable { public function price(): int; public function grams(): int; }
abstract class Book implements Sellable {
  public function __construct(protected string $code, protected int $cents) {}
  public function sku(): string { return self::PREFIX . $this->code; }
  public function price(): int { return intdiv($this->cents * (100 + static::TAX), 100); }
}
final class Paperback extends Book implements Shippable {     // price() serves both
  public function grams(): int { return 410; }
}
final class Ebook extends Book { public const int TAX = 8; }  // override: PHP 8.1+
foreach ([new Paperback('101', 2500), new Ebook('102', 1500)] as $b) {
  echo $b->sku(), ' ', $b::class, ' tax ', $b::TAX, '% ', $b->price(), "\n";
}
Output
BK-101 Paperback tax 6% 2650
BK-102 Ebook tax 8% 1620

Both Taxable and Shippable declare price(), and one method satisfies both; redefining PREFIX would stop the script with Ebook::PREFIX cannot override final constant HasSku::PREFIX. Older tutorials forbid both shared method names (allowed since PHP 5.3.9) and overridden interface constants (allowed since 8.1).