Interfaces, Traits, and Abstract Classes
PHP's OOP toolkit gives you three complementary tools for code organization: interfaces for contracts, abstract classes for shared structure, and traits for horizontal code reuse. Together, they solve the diamond problem without multiple inheritance.
// Interface: define the contract
interface Cacheable {
public function getCacheKey(): string;
public function getCacheTTL(): int;
}
// Trait: reuse implementation across unrelated classes
trait HasTimestamps {
public DateTimeImmutable $createdAt;
public ?DateTimeImmutable $updatedAt = null;
public function touch(): void {
$this->updatedAt = new DateTimeImmutable();
}
}
// Abstract class: shared structure with extension points
abstract class Model implements Cacheable {
use HasTimestamps;
abstract protected function tableName(): string;
public function getCacheKey(): string {
return $this->tableName() . ':' . $this->id;
}
public function getCacheTTL(): int {
return 3600;
}
}
// Concrete: just fill in the blanks
class User extends Model {
use SoftDeletes; // Another trait — compose freely
protected function tableName(): string {
return 'users';
}
}
The combination is powerful: interfaces ensure interoperability, abstract classes provide sensible defaults, and traits let you compose behavior horizontally without deep inheritance hierarchies. Modern PHP codebases are flat and composable, not deeply nested.
Significance: Architecture
PHP's three-tool OOP approach encourages composition over inheritance. You can define behavior contracts (interfaces), share default implementations (abstract classes), and mix in cross-cutting concerns (traits) — all without the complexity and fragility of multiple inheritance.