Interfaces
Learn how PHP interfaces define a contract of method signatures that unrelated classes can implement to guarantee shared behavior.
Introduction
In the last lesson, you saw how an abstract class can force its subclasses to implement certain methods while still sharing some common code. But what if two classes have nothing to do with each other — say, a CreditCard and a PayPal account — yet you still want a guarantee that both support the same operation, like being "paid"? Inheritance is not a good fit here, because these classes are not naturally related.
This is exactly the problem interfaces solve. An interface defines a contract — a list of method signatures — that any class can promise to fulfill, regardless of where that class sits in the inheritance tree.
- What an interface is and how it differs from a class.
- How to define an interface and implement it with the `implements` keyword.
- How a single class can implement multiple interfaces.
- Why interfaces let unrelated classes guarantee shared behavior.
- A worked example using a `Payable` interface.
What is an Interface?
An interface is a blueprint that lists method signatures — names, parameters, and return types — without any implementation. It contains no method bodies and (in most cases) no properties. It simply says: "any class that implements me must provide these methods."
An interface is like a job description. It lists what tasks must be performed, but it does not say how. Each class that "signs" the contract by implementing the interface decides how to actually do the work.
Defining an Interface
An interface is declared with the `interface` keyword, and each method inside it ends with a semicolon instead of a body.
<?php
interface Payable
{
public function pay(float $amount): string;
public function getPaymentMethodName(): string;
}Notice there is no code inside `pay()` or `getPaymentMethodName()` — just the signature. Interface methods are always implicitly public, since the whole point is to expose a public contract.
Implementing an Interface
A class uses the `implements` keyword to promise it will fulfill an interface's contract. PHP enforces this at the class level: if you forget to define a required method, PHP throws a fatal error.
<?php
class CreditCard implements Payable
{
public function __construct(private string $cardNumber) {}
public function pay(float $amount): string
{
return "Charged $" . number_format($amount, 2) . " to card ending in " . substr($this->cardNumber, -4);
}
public function getPaymentMethodName(): string
{
return "Credit Card";
}
}
$card = new CreditCard("4111111111111234");
echo $card->pay(49.99);Charged $49.99 to card ending in 1234Implementing Multiple Interfaces
PHP only allows a class to `extends` one parent class — single inheritance. Interfaces have no such limit. A class can implement as many interfaces as it needs, separated by commas.
<?php
interface Payable
{
public function pay(float $amount): string;
}
interface Refundable
{
public function refund(float $amount): string;
}
class CreditCard implements Payable, Refundable
{
public function pay(float $amount): string
{
return "Charged $" . number_format($amount, 2);
}
public function refund(float $amount): string
{
return "Refunded $" . number_format($amount, 2);
}
}
$card = new CreditCard();
echo $card->pay(20) . "\n";
echo $card->refund(20);Charged $20.00
Refunded $20.00A class can extend at most one parent class, but it can implement any number of interfaces. This is how PHP works around single inheritance to still give you flexible, multi-faceted class designs.
Why Interfaces Matter
Interfaces let you write code that depends on behavior, not on a specific class. A function that accepts anything "Payable" does not need to know or care whether it received a CreditCard, a PayPal account, or a BankTransfer object — it only cares that a `pay()` method exists.
This is a form of polymorphism that does not require a shared parent class. It is especially useful when the classes involved are conceptually unrelated but still need to support a common operation.
Worked Example: Payable
Here, `CreditCard` and `PayPal` share no inheritance relationship at all, yet both can be used anywhere a `Payable` is expected.
<?php
interface Payable
{
public function pay(float $amount): string;
}
class CreditCard implements Payable
{
public function pay(float $amount): string
{
return "Paid $" . number_format($amount, 2) . " via Credit Card";
}
}
class PayPal implements Payable
{
public function __construct(private string $email) {}
public function pay(float $amount): string
{
return "Paid $" . number_format($amount, 2) . " via PayPal ({$this->email})";
}
}
function checkout(Payable $method, float $amount): void
{
echo $method->pay($amount) . "\n";
}
checkout(new CreditCard(), 75);
checkout(new PayPal("shopper@example.com"), 30);Paid $75.00 via Credit Card
Paid $30.00 via PayPal (shopper@example.com)The `checkout()` function type-hints `Payable`, not a specific class. It works with any class that implements the interface, present or future — you could add a `BankTransfer` class next month and `checkout()` would accept it with zero changes.
Interfaces vs Abstract Classes
Interface
- No method implementations at all
- A class can implement many interfaces
- Used for unrelated classes sharing a capability
- No constructors or state
Abstract Class
- Can mix implemented and abstract methods
- A class can extend only one abstract class
- Used for closely related classes sharing code
- Can have constructors, properties, and state
Common Mistakes
- Trying to instantiate an interface directly — interfaces cannot be instantiated with `new`.
- Forgetting to implement every method listed in the interface, which causes a fatal error.
- Changing the method signature (parameters or visibility) when implementing an interface method.
- Using an interface when the classes actually share meaningful code — an abstract class may fit better.
Best Practices
- Name interfaces after a capability or role, such as Payable, Comparable, or Loggable.
- Keep interfaces small and focused on one responsibility rather than bundling unrelated methods.
- Type-hint against interfaces in function parameters so your code works with any conforming class.
- Combine interfaces with abstract classes when you need both a shared contract and shared code.
Frequently Asked Questions
Can an interface have properties?
No, interfaces can only declare method signatures and constants — not properties. Any state must live in the implementing class.
Can an interface extend another interface?
Yes. An interface can extend one or more other interfaces using `interface Child extends Parent1, Parent2 {}`, inheriting all their method signatures.
What happens if a class does not implement all interface methods?
PHP throws a fatal error at runtime: "Class must implement interface method", so the mistake surfaces immediately.
Can I create an instance of an interface?
No. Like abstract classes, interfaces cannot be instantiated directly with `new` — only concrete implementing classes can be.
Are interface methods always public?
Yes. All methods declared in an interface are implicitly public, since they define a public contract.
Key Takeaways
- An interface defines a contract of method signatures with no implementation.
- A class fulfills an interface using the `implements` keyword.
- A class can implement multiple interfaces, unlike single inheritance with `extends`.
- Interfaces let unrelated classes guarantee they support the same methods.
- Type-hinting against an interface lets your code work with any class that implements it.
Summary
Interfaces give you a way to define a shared contract without forcing unrelated classes into an inheritance hierarchy. Any class, no matter its ancestry, can implement an interface and be trusted to support its methods.
In this lesson, you learned how to define interfaces with `interface`, implement them with `implements`, implement multiple interfaces on one class, and why this matters for writing flexible, decoupled code. Next, you will learn about traits — another tool PHP offers for reusing code across unrelated classes.
- You understand what an interface is and how it differs from a class.
- You can define an interface and implement it in a class.
- You know a class can implement multiple interfaces.
- You can explain why interfaces enable polymorphism across unrelated classes.