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:

  1. A request comes from an external source (for example, a web request).

  2. An adapter receives the request and calls an input port.

  3. The input port triggers business logic in the domain.

  4. The domain may call output ports to interact with external systems.

  5. 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.