📡 You're offline — showing cached content
New version available!
Quick Access
Python Intermediate

PHP Interfaces vs Abstract Classes: When to Use Each

Definitively understand interfaces vs abstract classes in PHP — contracts vs implementation, multiple vs single inheritance, decision framework.

EzyCoders Admin December 6, 2025 10 min read 1 views
PHP Interfaces vs Abstract Classes Guide
Share: Twitter LinkedIn WhatsApp

Interfaces vs Abstract Classes

Knowing when to use an interface vs an abstract class is one of the most common PHP OOP interview questions. The answer depends on whether you're defining a capability contract or sharing implementation.

<?php
// Interface: WHAT a class must do (contract/capability)
interface Cacheable {
    public function getCacheKey(): string;
    public function getCacheTtl(): int;
    public function serialize(): string;
}

interface Searchable {
    public function getSearchableText(): string;
    public function getSearchWeight(): float;
}

// Class can implement MULTIPLE interfaces
class Post implements Cacheable, Searchable {
    public function getCacheKey(): string { return 'post:' . $this->id; }
    public function getCacheTtl(): int { return 3600; }
    public function serialize(): string { return json_encode($this->toArray()); }
    public function getSearchableText(): string { return $this->title . ' ' . $this->content; }
    public function getSearchWeight(): float { return 1.0; }
}

// Abstract class: shared implementation + forced overrides
abstract class BaseRepository {
    protected PDO $db;

    public function __construct(PDO $db) {
        $this->db = $db;  // concrete — shared by all children
    }

    // Concrete method — all children inherit this
    public function beginTransaction(): void {
        $this->db->beginTransaction();
    }

    // Abstract — each child MUST implement
    abstract public function findById(int $id): ?array;
    abstract public function save(array $data): int;
    abstract protected function getTable(): string;

    // Template Method pattern
    public function findAll(): array {
        return $this->db->query("SELECT * FROM {$this->getTable()}")->fetchAll();
    }
}

class UserRepository extends BaseRepository {
    protected function getTable(): string { return 'users'; }
    public function findById(int $id): ?array {
        $s = $this->db->prepare('SELECT * FROM users WHERE id=?');
        $s->execute([$id]);
        return $s->fetch() ?: null;
    }
    public function save(array $data): int {
        $s = $this->db->prepare('INSERT INTO users (name,email) VALUES (?,?)');
        $s->execute([$data['name'], $data['email']]);
        return (int)$this->db->lastInsertId();
    }
}
FeatureInterfaceAbstract Class
Multiple inheritanceYes (implement many)No (extend one)
ConstructorNot allowedAllowed
PropertiesConstants onlyAny visibility
Method bodiesNo (abstract only)Mix of both
Use whenDefining capabilitySharing implementation
EzyCoders Admin
Written by
EzyCoders Admin

Team Lead and Full-Stack Developer with experience in PHP, JavaScript, SQL, DSA, and System Design. Passionate about software engineering, scalable web technologies, and helping developers prepare for coding interviews and tech careers through practical tutorials and professional guidance.

Comments (0)

No comments yet. Be the first!

Leave a Comment