The Adapter Design Pattern in PHP is a structural pattern that solves one common problem: incompatible interfaces. It allows objects with different interfaces to work together by introducing a wrapper or “adapter” class. In real-world PHP projects, especially those involving legacy systems or third-party libraries, this pattern can save hours of rewriting code. Whether you’re integrating APIs, refactoring old code, or working in a team, the Adapter pattern ensures your objects can communicate, no matter their shape or origin.
In this article, we’ll explore the Adapter Design Pattern in PHP with simple, native PHP examples. You’ll see a bad approach, a clean solution, and how to use this pattern to future-proof your applications. By the end, you’ll know how and when to use this elegant design solution.
What Is the Adapter Design Pattern?
The Adapter Design Pattern acts as a bridge between two incompatible interfaces. Think of it like a power socket adapter: your laptop plug doesn’t match the outlet, so you use an adapter to make them compatible.
In PHP, this means creating a new class (adapter) that implements the interface your system expects, while internally calling methods on an existing class that has a different interface.
When to Use the Adapter Design Pattern in PHP
- You’re integrating a third-party library that doesn’t match your application’s interfaces.
- You want to reuse legacy code without changing it.
- You’re working with classes that perform similar tasks but use different method names or parameters.
Using this pattern helps in keeping your code clean, consistent, and open for extension but closed for modification—a key principle in SOLID design.
Bad Example: No Adapter, No Compatibility
Here’s what happens when you force incompatible classes to work together without using an adapter:
class OldPaymentGateway {
public function sendPayment(float $amount) {
echo "Paying $amount via old gateway.";
}
}
class Checkout {
public function processPayment(OldPaymentGateway $gateway, float $amount) {
// This only works with OldPaymentGateway
$gateway->sendPayment($amount);
}
}
This setup tightly couples Checkout
to OldPaymentGateway
, making it impossible to switch to a new gateway without rewriting code. It’s rigid and unscalable.
Good Example: Adapter Design Pattern in PHP
Let’s fix this using the Adapter Design Pattern in PHP.
// Target interface
interface PaymentProcessor {
public function pay(float $amount);
}
// Adaptee: existing class with a different method
class OldPaymentGateway {
public function sendPayment(float $amount) {
echo "Paying $amount via old gateway.";
}
}
// Adapter: adapts OldPaymentGateway to PaymentProcessor
class OldGatewayAdapter implements PaymentProcessor {
private OldPaymentGateway $gateway;
public function __construct(OldPaymentGateway $gateway) {
$this->gateway = $gateway;
}
public function pay(float $amount) {
$this->gateway->sendPayment($amount);
}
}
// Client code
class Checkout {
public function processPayment(PaymentProcessor $processor, float $amount) {
$processor->pay($amount);
}
}
// Usage
$gateway = new OldPaymentGateway();
$adapter = new OldGatewayAdapter($gateway);
$checkout = new Checkout();
$checkout->processPayment($adapter, 99.99);
This approach decouples Checkout
from the specific implementation of OldPaymentGateway
. Now, any class implementing PaymentProcessor
can be plugged in easily.
Benefits of the Adapter Design Pattern in PHP
- ✅ Improves compatibility between unrelated interfaces.
- ✅ Promotes reusable code by abstracting specific implementations.
- ✅ Future-proofs applications when dealing with external systems.
- ✅ Reduces technical debt, especially in legacy systems.
- ✅ Improves testing by making components easily mockable.
Adapter Pattern Variants in PHP
There are two common types of adapter implementations:
- Class Adapter (uses inheritance)
PHP doesn’t support multiple inheritance, so this is less common.
- Object Adapter (uses composition)
This is the example we used above. It’s the preferred way in PHP.
Real-World Use Cases
- PSR Adapters: Libraries like Guzzle or Monolog use adapter patterns to comply with PSR standards.
- API Integration: Wrapping third-party APIs to match your internal data model.
- Legacy Systems: Interfacing legacy PHP classes with modern Laravel or Symfony apps.
Final Thoughts
The Adapter Design Pattern in PHP is your go-to solution when working with incompatible interfaces. It keeps your code maintainable, scalable, and clean—especially when dealing with third-party libraries or old codebases. Instead of rewriting or duplicating logic, wrap it, adapt it, and move forward with confidence.
Remember, clean code isn’t just about what works—it’s about what keeps working as your application grows.
Interested in More Design Patterns?
Discover other powerful patterns like Factory, Strategy, and Observer in this full guide: