Enforce PHP Interface Implementation with Implements
In PHP, ensuring that classes adhere to a specific structure is
crucial for building robust, decoupled, and maintainable applications.
This article provides a straightforward guide on how to strictly enforce
interface implementation in PHP using the implements
keyword. You will learn how to define interfaces, apply them to classes,
use type hinting for strict enforcement, and understand how PHP handles
compliance errors at runtime.
Defining an Interface
An interface acts as a contract. It defines the method names, arguments, and return types that a class must implement, without providing the actual business logic.
To create an interface, use the interface keyword:
interface PaymentProcessorInterface
{
public function processPayment(float $amount): bool;
}Implementing the Interface
To enforce this contract on a class, use the implements
keyword. Once a class implements an interface, it must define all the
methods declared in that interface. The method signatures—including the
number of arguments, type hints, and return types—must match the
interface exactly.
class StripeProcessor implements PaymentProcessorInterface
{
public function processPayment(float $amount): bool
{
// Payment processing logic goes here
return true;
}
}How PHP Enforces the Contract
PHP strictly enforces interface implementation at the engine level. If a class claims to implement an interface but fails to define one of its methods, or defines a method with an incompatible signature, PHP will immediately halt execution and throw a fatal error.
For example, the following code will fail:
// This will trigger a Fatal Error
class PayPalProcessor implements PaymentProcessorInterface
{
// Fatal Error: Class PayPalProcessor contains 1 abstract method
// and must therefore be declared abstract or implement the remaining methods
}Similarly, changing the parameter type or return type in the class will trigger a fatal error due to signature incompatibility:
// This will also trigger a Fatal Error
class BankProcessor implements PaymentProcessorInterface
{
// Error: Declaration of BankProcessor::processPayment(int $amount)
// must be compatible with PaymentProcessorInterface::processPayment(float $amount)
public function processPayment(int $amount): bool
{
return true;
}
}Enforcing Interfaces via Type Hinting
Defining the interface is only the first step. To strictly enforce its usage throughout your application, you should use the interface name as a type hint in your functions and methods. This ensures that the receiving code only accepts objects that are guaranteed to have the required methods.
class OrderManager
{
private PaymentProcessorInterface $paymentProcessor;
// Type hinting enforces that only valid implementations can be injected
public function __construct(PaymentProcessorInterface $paymentProcessor)
{
$this->paymentProcessor = $paymentProcessor;
}
public function checkout(float $total)
{
$this->paymentProcessor->processPayment($total);
}
}If you attempt to pass a class to OrderManager that does
not implement PaymentProcessorInterface, PHP will throw a
TypeError, preventing invalid objects from breaking your
application logic.