PHP Interfaces

Connecting Components via Contracts

Oleh: Ahmad Muyassar, S.Kom.,M.Cs

System Protocols

01. Konsep Interface
02. Syntax: interface & implements
03. Multiple Inheritance
04. Interface vs Abstract Class
05. Polymorphism & Type Hinting
01

The Contract

Apa itu Interface?

Analogi: Stopkontak

Stopkontak listrik adalah sebuah Interface.

Definisi Interface

Interface adalah struktur pemrograman yang mendefinisikan KONTRAK method apa saja yang harus dimiliki oleh sebuah class, tanpa mendefinisikan cara kerjanya.

Semua method dalam interface otomatis bersifat public dan abstract.

02

Syntax

Keyword: interface & implements

Mendefinisikan Interface

Gunakan keyword interface.


interface Logger {
    public function log($message);
    public function error($message);
}
            

Perhatikan: Tidak ada body method {}.

Mengimplementasikan Interface

Gunakan keyword implements pada class.


class FileLogger implements Logger {
    public function log($message) {
        // Tulis ke file log.txt
        file_put_contents('log.txt', $message, FILE_APPEND);
    }

    public function error($message) {
        // Tulis error
        $this->log("[ERROR] " . $message);
    }
}
            

Aturan Main

Jika sebuah class meng-implements sebuah interface, class tersebut WAJIB mendefinisikan ulang (override) SEMUA method yang ada di interface tersebut.

Jika kurang satu saja, akan terjadi Fatal Error!

Database Logger

Kita bisa membuat implementasi lain yang berbeda total.


class DatabaseLogger implements Logger {
    public function log($message) {
        // Insert ke tabel logs di database
        $db->query("INSERT INTO logs ...");
    }

    public function error($message) {
        // ...
    }
}
            
03

Multiple Inheritance

Melampaui Batas Abstract Class

Keterbatasan Class

Di PHP, sebuah class hanya bisa extends SATU parent class.


class SmartPhone extends Phone, Computer { // ERROR! }
            

Solusi Interface

Sebuah class bisa meng-implements BANYAK interface sekaligus. Ini adalah cara PHP meniru Multiple Inheritance.


class SmartPhone implements Phone, Computer, Camera {
    // Wajib implementasi method dari Phone
    // Wajib implementasi method dari Computer
    // Wajib implementasi method dari Camera
}
            

Contoh Multiple Interface


interface CanFly {
    public function fly();
}

interface CanSwim {
    public function swim();
}

class Duck implements CanFly, CanSwim {
    public function fly() { echo "Bebek terbang rendah"; }
    public function swim() { echo "Bebek berenang"; }
}
            
04

Vs Abstract Class

Kapan Pakai Yang Mana?

Perbedaan Utama

Fitur Interface Abstract Class
Method Body Tidak Boleh Boleh (Partial Implementation)
Properties Hanya Konstanta Boleh Variable ($state)
Inheritance Multiple (implements) Single (extends)
Keyword implements extends

Kapan Pakai Interface?

Gunakan Interface ketika Anda ingin mendefinisikan KEMAMPUAN (Capability) yang bisa dimiliki oleh berbagai class yang tidak saling berhubungan.

Contoh: Loggable, Countable, JsonSerializable.

Kapan Pakai Abstract Class?

Gunakan Abstract Class ketika Anda ingin membuat TEMPLATE DASAR untuk class-class yang memiliki hubungan erat ("is-a").

Contoh: User (abstract) -> Admin, Member.

05

Polymorphism

Type Hinting dengan Interface

Kekuatan Sejati Interface

Kekuatan utama interface bukan pada pembuatannya, tapi pada penggunaannya sebagai Type Hint di fungsi/method.

Tanpa Interface (Kaku)


class UserProfile {
    public function update(FileLogger $logger) {
        // ... update profile
        $logger->log("Profile updated");
    }
}
            

Masalah: Fungsi ini HANYA bisa menerima FileLogger. Kalau mau ganti ke DatabaseLogger, harus ubah kode!

Dengan Interface (Fleksibel)


class UserProfile {
    // Type Hint ke Interface, bukan Class konkret
    public function update(Logger $logger) {
        // ... update profile
        $logger->log("Profile updated");
    }
}
            

Sekarang fungsi ini bisa menerima APAPUN, asalkan benda itu adalah Logger.

Dependency Injection

Ini adalah dasar dari prinsip Dependency Injection dan Inversion of Control.


$fileLog = new FileLogger();
$dbLog = new DatabaseLogger();

$profile = new UserProfile();

// Bisa pakai File
$profile->update($fileLog);

// Bisa pakai Database, tanpa ubah kode UserProfile!
$profile->update($dbLog);
            
06

Repository Pattern

Contoh Dunia Nyata

Masalah

Aplikasi kita saat ini menggunakan MySQL. Tapi mungkin tahun depan kita ingin pindah ke MongoDB atau Firebase.

Jika kode query MySQL tersebar di mana-mana, migrasi akan sangat sulit.

Solusi: Repository Interface


interface UserRepository {
    public function all();
    public function find($id);
    public function save($data);
}
            

MySQL Implementation


class EloquentUserRepository implements UserRepository {
    public function find($id) {
        return User::find($id); // Eloquent ORM
    }
    // ...
}
            

MongoDB Implementation


class MongoUserRepository implements UserRepository {
    public function find($id) {
        return $this->mongo->collection('users')->findOne(['_id' => $id]);
    }
    // ...
}
            

Controller (Agnostik)


class UserController {
    private $repo;

    // Controller tidak peduli databasenya apa!
    public function __construct(UserRepository $repo) {
        $this->repo = $repo;
    }

    public function show($id) {
        $user = $this->repo->find($id);
        return view('user.profile', ['user' => $user]);
    }
}
            

Keuntungan

Built-in Interfaces PHP

PHP sendiri menyediakan banyak interface bawaan yang sakti.

Contoh JsonSerializable


class User implements JsonSerializable {
    public function jsonSerialize() {
        return [
            'id' => $this->id,
            'name' => $this->name,
            // Password tidak ikut diserialisasi!
        ];
    }
}

echo json_encode(new User());
            

Interface Constants

Interface bisa memiliki konstanta, yang otomatis diwariskan ke class implementornya.


interface Status {
    const ACTIVE = 1;
    const INACTIVE = 0;
}

class User implements Status {
    public function activate() {
        $this->status = self::ACTIVE;
    }
}
            

Kesimpulan

Terima Kasih

Connection Terminated.

1 / 35