Clean Architecture for PHP & Slim framework.

Sahbi Jabnouni
4 min readJul 27, 2020

--

“Good architecture makes the system easy to understand, easy to develop, easy to maintain, and easy to deploy. The ultimate goal is to minimize the lifetime cost of the system and to maximize programmer productivity.”
Robert C. Martin

What’s clean architecture

Clean architecture is a method for organizing an application code. The method is defined by Robert C Martin in his book Clean Architecture: A Craftsman’s Guide to Software Structure and Design.

The goal of the clean architecture method is the separation of concerns of the application.

The benefits of using the clean architecture method are creating a simple, loosely-coupled and testable application.

Like many other methods clean architecture separates the application in different layers:

Entities

Entities layer contains the application business objects. The business objects can have business roles or just data structures. The business roles should depend only on the entity and not on any external system.

Use Cases

The Use Cases layer contains all the system use cases, and it is used for implementing all the application-specific business rules. The Use Cases layer is used to transfer the data from and to the entities and it depends on abstract interfaces to communicate with the higher layers.

Adapters

The Adapters layer contains the implementations for transferring and transforming the data from the external systems (Database, browser etc…) to the application and from the application to the external systems. Adapters layer can have the persistence, API and UI implementations.

Frameworks and drivers

Frameworks and drivers layer contains the tools that are used by the application. These tools can be a database, web framework, monitoring tool, etc. The choice of these tools should not be very critical, and the tools should be easy to replace.

Characteristics

- Abstraction

Entities and Use Cases layers have the highest level of abstraction. On the other hand, the Adapters layer has more concrete implementations and a lower level of abstraction.

- Changeability

Adapters layer has more and frequent changes. Most of the changes in the Adapters layer come from fixing and maintaining the implementations.

Entities and Use Cases layers have fewer changes. Once these layers are created, they will have almost no changes because they don’t have any concrete implementation.

- Dependency

The higher layers depend on the lower layers. Adapters layer depends on Uses Cases and Entities layers and Use Cases layer depends on Entities layer.
A lower layer should never depend on the higher layer.
Use Cases and Entities layers should not have any dependencies on tools or frameworks.

PHP and Slim Framework code example

Scenario:

In this example, we will show how to implement a simple User Management API by following the clean architecture method.

The use cases are: add a user and find a user by id. The user data will be stored in a database (Any database, we will use sqlite for this example).

Check the complete code in https://github.com/sahbijabnouni/clean-architecture-php

Entities layer

User: Contains user data structure.

Use Cases layer

UserManager: Contains all the user use cases

UserRepositoryInterface: An abstraction of user data persistence implementation and it is used by the UserManager.

Adapters layer

UserRepository: Implementation for storing/retrieving user data in the database.

UserController: Used for receiving API requests and returning responses.

Dependency Injection:

Dependency injection is a design pattern that allows the creation of dependencies outside of the callers.
Dependency injection helps maintain the separation between the layers and makes the testing easier.

In our example, we use PHP-DI for implementing the Dependency injection.

Running the example:

pull the code from https://github.com/sahbijabnouni/clean-architecture-php
Install the libraries and run the API:
composer install
composer start
Add user:
curl -d '{"id":"1", "firstName":"firstname","lastName":"lastname", "email":"myemail@example.com"}' -H "Content-Type: application/json" -X POST http://localhost:8080/users
Get user:
curl -H "Content-Type: application/json" -X GET http://localhost:8080/users/1

Conclusion

Using a good design for our application can help us be more productive, make it easy to add new features, replace dependencies, maintain and test code. Clean architecture is one of the best approaches to achieve good design and create high-quality applications.

Thanks for reading! Let me know if you have any questions or need help.

--

--