PHP Interfaces: How to Define Contracts in PHP Classes

Interfaces are one of those PHP features that look unnecessary when you are working on a small script. Then one day your application grows, a new payment provider needs to be added, a logger needs to be replaced, or a service needs better testing. Suddenly, interfaces start making a lot more sense.

In PHP, an interface defines a contract that classes must follow. It tells a class which methods it must provide, but it does not decide how those methods should work.

This separation allows different classes to provide their own implementations while still being used in the same way. It helps reduce tight coupling and makes large PHP applications easier to maintain.

Quick Answer: What is an interface in PHP?

A PHP interface is a structure that defines a set of public method signatures that a class must implement. A class uses the implements keyword to follow an interface.

For example:

<?php

interface Logger
{
    public function log(string $message): void;
}

class FileLogger implements Logger
{
    public function log(string $message): void
    {
        echo "Saving log to file: " . $message;
    }
}

$logger = new FileLogger();
$logger->log("User logged in");

?>

The Logger interface does not contain the logging logic. It only defines that any logger must have a log() method.

The FileLogger class provides the actual implementation.

Why use interfaces in PHP?

The main purpose of an interface is to allow your code to depend on behaviour instead of a specific class.

Consider an application that sends notifications. Initially, you may send emails only. Later, you may want to add SMS or push notifications.

Without an interface, your application code may become tightly connected to one notification class. Changing the implementation can require changes in many places.

With an interface, the application only expects a notification service that follows a known contract.

This idea is often called programming to an interface.

Interfaces are especially useful for:

  • Replacing one implementation with another.
  • Writing easier-to-test code using mock implementations.
  • Allowing unrelated classes to share common behaviour.
  • Building flexible systems where new features can be added without modifying existing code.

If you are revisiting PHP object-oriented concepts, this article fits well alongside the PHP OOP concepts guide, especially classes, inheritance, and abstraction.

Creating an interface in PHP

An interface is created using the interface keyword.

<?php

interface PaymentGateway
{
    public function pay(float $amount): bool;
}

?>

The interface above declares a pay() method. Any class implementing PaymentGateway must provide this method.

The interface only defines the method signature. It does not contain the method body.

Implementing an interface in PHP

A class implements an interface by using the implements keyword.

<?php

interface PaymentGateway
{
    public function pay(float $amount): bool;
}

class StripePayment implements PaymentGateway
{
    public function pay(float $amount): bool
    {
        echo "Processing payment of $" . $amount;

        return true;
    }
}

$payment = new StripePayment();
$payment->pay(100);

?>

The StripePayment class must define the pay() method because it implements PaymentGateway.

If the class does not implement all required methods, PHP throws a fatal error. The method signatures must also remain compatible with the interface definition. See the official PHP documentation for more details about PHP object interfaces.

Interface method rules in PHP

When a class implements an interface, PHP expects the class to follow the contract exactly. There are a few important rules to remember.

Interface methods must be public

All methods declared inside an interface are public by default. You cannot define private or protected methods in an interface.

<?php

interface Report
{
    public function generate(): string;
}

class SalesReport implements Report
{
    public function generate(): string
    {
        return "Sales report generated";
    }
}

?>

The implementing method must also be public.

Implemented methods must match the signature

The method name, parameters, and return type should match the interface definition.

For example, this implementation is invalid:

<?php

interface Exporter
{
    public function export(string $filename): bool;
}

class CsvExporter implements Exporter
{
    public function export($filename)
    {
        return true;
    }
}

?>

The parameter type is missing in the class implementation. PHP will report an error because the method signature does not satisfy the interface contract.

Keeping method signatures consistent makes the interface reliable for other parts of the application.

Multiple interface implementation in PHP

A PHP class can implement more than one interface. Multiple interfaces are separated using commas.

<?php

interface Printable
{
    public function print(): void;
}

interface Shareable
{
    public function share(): void;
}

class Document implements Printable, Shareable
{
    public function print(): void
    {
        echo "Printing document";
    }

    public function share(): void
    {
        echo "Sharing document";
    }
}

$document = new Document();

$document->print();
$document->share();

?>

Here, the Document class follows two separate contracts. This is useful when a class has multiple responsibilities that can be described independently.

Extending interfaces in PHP

Interfaces can extend other interfaces using the extends keyword.

Unlike classes, an interface can extend multiple interfaces.

<?php

interface Reader
{
    public function read(): string;
}

interface Writer
{
    public function write(string $data): void;
}

interface FileHandler extends Reader, Writer
{
}

class TextFile implements FileHandler
{
    public function read(): string
    {
        return "File content";
    }

    public function write(string $data): void
    {
        echo "Writing: " . $data;
    }
}

?>

The FileHandler interface inherits the requirements of both Reader and Writer. Any class implementing FileHandler must provide both methods.

Using interfaces for dependency injection

One of the most practical uses of interfaces in PHP is dependency injection.

Instead of forcing a class to depend on a specific implementation, you can make it depend on an interface.

For example, consider an order service that needs to send notifications.

<?php

interface Notification
{
    public function send(string $message): void;
}

class EmailNotification implements Notification
{
    public function send(string $message): void
    {
        echo "Email sent: " . $message;
    }
}

class OrderService
{
    private Notification $notification;

    public function __construct(Notification $notification)
    {
        $this->notification = $notification;
    }

    public function placeOrder(): void
    {
        echo "Order placed";

        $this->notification->send("Your order is confirmed");
    }
}

$order = new OrderService(new EmailNotification());

$order->placeOrder();

?>

The OrderService class does not know or care whether the notification is sent through email, SMS, or another service. It only knows that the object follows the Notification interface.

This makes future changes easier. Adding an SMS notification class does not require changing the order processing code.

Interface vs abstract class in PHP

Interfaces and abstract classes are often confused because both help define common behaviour. However, they solve different problems.

Interface Abstract class
Defines a contract that classes must follow. Provides a base class that child classes can inherit from.
A class can implement multiple interfaces. A class can extend only one abstract class.
Does not contain instance properties or implementation logic. Can contain properties, concrete methods, and abstract methods.
Useful when unrelated classes need the same behaviour. Useful when related classes share common code.

A simple way to remember the difference:

  • An interface says: “This class must be able to do this.”
  • An abstract class says: “This class is a type of this thing and can reuse this code.”

For example, a payment system may have different payment classes such as credit card, PayPal, and bank transfer. They are different types of objects, but they can all implement a common PaymentGateway interface.

On the other hand, different types of reports may share common formatting code. In that case, an abstract class may be a better fit.

Common mistakes when using PHP interfaces

Creating interfaces with too many methods

An interface should describe a focused contract. Adding unrelated methods forces every implementing class to provide methods it does not actually need.

For example, this design can become difficult to maintain:

interface UserManager
{
    public function createUser(): void;

    public function deleteUser(): void;

    public function sendEmail(): void;

    public function generateReport(): void;
}

A class that only needs user creation should not be forced to implement email and reporting methods.

Smaller interfaces are usually easier to maintain. This idea is related to the Interface Segregation Principle from the SOLID principles.

Using interfaces without a real need

Not every class needs an interface. Adding interfaces everywhere can make a small application harder to understand.

A useful question to ask is:

“Will I need multiple implementations of this behaviour, or will this class likely change?”

If the answer is no, a simple class may be enough.

Changing an interface frequently

An interface is a contract shared by multiple classes. Changing it can affect every class that implements it.

Before adding a new method to an existing interface, consider whether a new interface would be cleaner.

PHP interface constants

Interfaces can also define constants. These constants are available to classes that implement the interface.

<?php

interface Config
{
    public const VERSION = "1.0";
}

class Application implements Config
{
    public function showVersion(): void
    {
        echo self::VERSION;
    }
}

$app = new Application();

$app->showVersion();

?>

Interface constants are useful for values that belong to a shared contract. However, avoid using interfaces as a general container for unrelated constants. A dedicated configuration class is usually a better choice for application settings.

Benefits of using interfaces in PHP applications

Well-designed interfaces provide several practical advantages:

  • Loose coupling: Classes depend on behaviour instead of specific implementations.
  • Easy replacements: One implementation can be swapped with another.
  • Better testing: Mock implementations can be injected during tests.
  • Clear design: The expected behaviour of a class is documented through the interface.
  • Better scalability: New features can be added with fewer changes to existing code.

PHP interfaces in real-world applications

In small PHP applications, interfaces may feel like extra work. A class with a few methods is often enough. The value of interfaces becomes clearer when an application starts growing.

For example, imagine an application that stores uploaded files. Initially, files are stored locally. Later, the application needs support for cloud storage.

Instead of changing every part of the application that handles files, you can define a storage contract.

<?php

interface FileStorage
{
    public function upload(string $filename): bool;
}

class LocalStorage implements FileStorage
{
    public function upload(string $filename): bool
    {
        echo "Uploading {$filename} to local storage";

        return true;
    }
}

class CloudStorage implements FileStorage
{
    public function upload(string $filename): bool
    {
        echo "Uploading {$filename} to cloud storage";

        return true;
    }
}

class FileUploader
{
    private FileStorage $storage;

    public function __construct(FileStorage $storage)
    {
        $this->storage = $storage;
    }

    public function uploadFile(string $filename): void
    {
        $this->storage->upload($filename);
    }
}

$uploader = new FileUploader(new LocalStorage());

$uploader->uploadFile("photo.jpg");

?>

The FileUploader class works with any storage system that follows the FileStorage interface.

This pattern is common in frameworks and large PHP applications. The framework code often depends on contracts, while individual applications provide the actual implementations.

Frequently asked questions about PHP interfaces

Can a PHP interface have method implementations?

No. A traditional PHP interface only defines method signatures. The implementing class provides the method implementation.

However, PHP interfaces can contain constants and, in newer PHP versions, can work with features such as interface inheritance.

Can a class implement multiple interfaces in PHP?

Yes. A PHP class can implement multiple interfaces by separating them with commas.

class Invoice implements Printable, Shareable
{
    // Implement required methods
}

Can an interface extend another interface?

Yes. An interface can extend one or more interfaces using the extends keyword.

Can a trait implement an interface in PHP?

No. A trait cannot directly implement an interface. The class using the trait can implement the interface.

<?php

interface Cache
{
    public function store(string $key, string $value): void;
}

trait CacheHelper
{
    public function clear(): void
    {
        echo "Cache cleared";
    }
}

class FileCache implements Cache
{
    use CacheHelper;

    public function store(string $key, string $value): void
    {
        echo "Saving cache value";
    }
}

?>

When should I use an interface in PHP?

Use an interface when:

  • Multiple classes should provide the same type of behaviour.
  • You want to replace an implementation without changing the consuming code.
  • You want classes to depend on a contract instead of a concrete class.

Avoid adding interfaces only because they appear in design pattern examples. Good design is not about adding more layers. It is about creating useful boundaries where change is expected.

Conclusion

PHP interfaces provide a simple way to define contracts between classes. They do not contain the actual business logic. Instead, they describe what a class should be able to do.

When used properly, interfaces make PHP applications easier to extend, test, and maintain. They are especially valuable when your code starts having multiple implementations of the same behaviour.

The best time to introduce an interface is not when you first create a class. It is when you see a clear need for flexibility, replacement, or separation between your code components.

Photo of Vincy, PHP developer
Written by Vincy Last updated: July 23, 2026
I'm a PHP developer with 20+ years of experience and a Master's degree in Computer Science. I build and improve production PHP systems for eCommerce, payments, webhooks, and integrations, including legacy upgrades (PHP 5/7 to PHP 8.x).

Continue Learning

These related tutorials may help you continue learning.

4 Comments on "PHP Interfaces: How to Define Contracts in PHP Classes"

Leave a Reply

Your email address will not be published. Required fields are marked *

Explore topics
Need PHP help?