PHP - Hexagonal Architecture in PHP
Hexagonal Architecture, also known as Ports and Adapters Architecture, is a software design pattern that focuses on separating the core business logic of an application from external systems such as databases, user interfaces, and third-party services. The goal is to make the application more maintainable, testable, and independent of external technologies.
Core Idea of Hexagonal Architecture
The central idea is that the application’s core logic should not depend on external systems. Instead, all external interactions happen through well-defined interfaces called ports, and the actual implementations of those interactions are handled by adapters.
This creates a clear boundary between the core application and the outside world.
Structure of Hexagonal Architecture
Hexagonal Architecture is typically divided into three main parts:
1. Domain (Core)
This is the heart of the application. It contains:
-
Business rules
-
Entities
-
Value objects
-
Domain services
The domain does not depend on any external system or framework.
2. Ports
Ports are interfaces that define how the core communicates with the outside world. There are two types:
-
Input Ports: Define how external systems interact with the application (for example, use cases or services)
-
Output Ports: Define how the application interacts with external systems (such as databases or APIs)
Ports act as contracts that must be implemented by adapters.
3. Adapters
Adapters are the implementations of the ports. They connect the application to external systems.
Examples include:
-
Database adapters
-
API clients
-
Web controllers
-
CLI interfaces
Adapters convert external data into a format the core understands and vice versa.
How It Works
Instead of the application depending directly on a database or framework, it depends on interfaces. External systems implement those interfaces and plug into the application.
Flow of execution:
-
A request comes from an external source (for example, a web request).
-
An adapter receives the request and calls an input port.
-
The input port triggers business logic in the domain.
-
The domain may call output ports to interact with external systems.
-
Adapters implement those output ports and handle the actual operations.
Example in PHP
Step 1: Define an Output Port
interface UserRepository {
public function save(User $user);
}
Step 2: Domain Entity
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
Step 3: Use Case (Input Port)
class CreateUser {
private $repository;
public function __construct(UserRepository $repository) {
$this->repository = $repository;
}
public function execute($name) {
$user = new User($name);
$this->repository->save($user);
}
}
Step 4: Adapter Implementation
class MySQLUserRepository implements UserRepository {
public function save(User $user) {
echo "Saving user " . $user->name . " to database";
}
}
Step 5: Connecting Everything
$repository = new MySQLUserRepository();
$useCase = new CreateUser($repository);
$useCase->execute("John");
In this setup, the core logic does not depend on MySQL or any database directly.
Benefits of Hexagonal Architecture
Independence from Frameworks
The core logic does not depend on frameworks like Laravel or Symfony. This allows switching frameworks without affecting business logic.
High Testability
Since dependencies are injected through interfaces, it is easy to replace them with mocks during testing.
Flexibility
You can swap adapters without modifying the core. For example, changing a database from MySQL to MongoDB requires only a new adapter.
Clear Separation of Concerns
Business logic is isolated from infrastructure and delivery mechanisms.
Challenges
Increased Complexity
The architecture introduces more layers, which may feel complex for small projects.
More Boilerplate Code
Interfaces and adapters require additional code compared to simple designs.
Learning Curve
Understanding ports and adapters may take time for beginners.
When to Use Hexagonal Architecture
-
Large applications with complex business logic
-
Systems that require long-term maintainability
-
Projects that may change infrastructure over time
-
Applications that need strong test coverage
Comparison with Traditional Architecture
In traditional layered architecture:
-
The business logic often depends on the database
-
Changing infrastructure requires modifying core logic
In hexagonal architecture:
-
The core is completely independent
-
External systems depend on the core, not the other way around
Conclusion
Hexagonal Architecture in PHP provides a structured approach to building applications where business logic remains independent of external systems. By using ports and adapters, it ensures flexibility, testability, and maintainability. Although it introduces additional complexity, it is highly valuable for building scalable and long-lasting applications where changes in technology should not affect the core business rules.