| name | acc-layer-arch-knowledge |
| description | Layered Architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for traditional N-tier/Layered Architecture audits. |
Layered Architecture Knowledge Base
Quick reference for Layered (N-Tier) Architecture patterns and PHP implementation guidelines.
Core Principles
Layered Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
│ (Controllers, Views, API Endpoints, CLI) │
│ │
│ Responsibilities: │
│ - Handle user input │
│ - Display output │
│ - Validate input format │
│ - Route requests │
└───────────────────────────┬─────────────────────────────────────┘
│ calls
▼
┌─────────────────────────────────────────────────────────────────┐
│ APPLICATION LAYER │
│ (Services, Use Cases, DTOs, Facades) │
│ │
│ Responsibilities: │
│ - Orchestrate business operations │
│ - Transaction management │
│ - Coordinate domain objects │
│ - Map between layers │
└───────────────────────────┬─────────────────────────────────────┘
│ calls
▼
┌─────────────────────────────────────────────────────────────────┐
│ DOMAIN LAYER │
│ (Entities, Value Objects, Domain Services, Rules) │
│ │
│ Responsibilities: │
│ - Business logic │
│ - Business rules and invariants │
│ - Domain events │
│ - Core algorithms │
└───────────────────────────┬─────────────────────────────────────┘
│ calls
▼
┌─────────────────────────────────────────────────────────────────┐
│ INFRASTRUCTURE LAYER │
│ (Repositories, External APIs, Database, Cache) │
│ │
│ Responsibilities: │
│ - Data persistence │
│ - External service integration │
│ - Technical infrastructure │
│ - Framework-specific code │
└─────────────────────────────────────────────────────────────────┘
Core Rule: Each layer only communicates with the layer directly below it.
Layer Communication Rules
| From Layer | Can Call | Cannot Call |
|---|
| Presentation | Application | Domain, Infrastructure |
| Application | Domain, Infrastructure | Presentation |
| Domain | Infrastructure (via interfaces) | Presentation, Application |
| Infrastructure | — | All upper layers |
Quick Checklists
Presentation Layer Checklist
Application Layer Checklist
Domain Layer Checklist
Infrastructure Layer Checklist
Common Violations Quick Reference
| Violation | Where to Look | Severity |
|---|
| Skipping layers | Controller calling DB | Critical |
| Upward dependency | Domain using Application | Critical |
| Business in Controller | if/switch in controllers | Warning |
| Anemic services | Service = simple delegation | Warning |
| Fat repository | Logic in repository | Warning |
PHP 8.5 Layered Architecture Patterns
Presentation Layer (Controller)
<?php
declare(strict_types=1);
namespace Presentation\Api\Order;
use Application\Order\Service\OrderService;
use Application\Order\DTO\CreateOrderDTO;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
final readonly class OrderController
{
public function __construct(
private OrderService $orderService
) {}
public function create(Request $request): JsonResponse
{
$dto = CreateOrderDTO::fromRequest($request);
$result = $this->orderService->createOrder($dto);
return new (->(), );
}
{
= ->orderService->();
(->());
}
}
Application Layer (Service)
<?php
declare(strict_types=1);
namespace Application\Order\Service;
use Application\Order\DTO\CreateOrderDTO;
use Application\Order\DTO\OrderDTO;
use Domain\Order\Entity\Order;
use Domain\Order\Repository\OrderRepositoryInterface;
use Domain\Order\ValueObject\OrderId;
final readonly class OrderService
{
public function __construct(
private OrderRepositoryInterface $orderRepository,
private TransactionManagerInterface $transactionManager
) {}
public function createOrder(CreateOrderDTO $dto): OrderDTO
{
return $this->transactionManager->(function () ($) {
$ = ::(
: $->->(),
: $->,
: $->
);
->orderRepository->();
OrderDTO::();
});
}
{
= ->orderRepository->( ());
( === ) {
();
}
OrderDTO::();
}
}
Domain Layer (Entity)
<?php
declare(strict_types=1);
namespace Domain\Order\Entity;
use Domain\Order\ValueObject\OrderId;
use Domain\Order\ValueObject\CustomerId;
use Domain\Order\ValueObject\Money;
use Domain\Order\Enum\OrderStatus;
final class Order
{
private OrderStatus $status;
private array $lines = [];
public function __construct(
private readonly OrderId $id,
private readonly CustomerId $customerId
) {
$this->status = OrderStatus::Draft;
}
public static function create(OrderId , CustomerId , ):
{
= (, );
( ) {
->();
}
;
}
{
(!->()) {
();
}
->status = ::;
}
{
(
->lines,
fn (Money , OrderLine ) => ->(->()),
::()
);
}
{
->status === :: && !(->lines);
}
}
Infrastructure Layer (Repository)
<?php
declare(strict_types=1);
namespace Infrastructure\Persistence\Order;
use Domain\Order\Entity\Order;
use Domain\Order\Repository\OrderRepositoryInterface;
use Domain\Order\ValueObject\OrderId;
use Doctrine\ORM\EntityManagerInterface;
final readonly class DoctrineOrderRepository implements OrderRepositoryInterface
{
public function __construct(
private EntityManagerInterface $em
) {}
public function findById(OrderId $id): ?Order
{
return $this->em->find(Order::class, $id->value);
}
public ():
{
->em->();
->em->();
}
{
::();
}
}
References
For detailed information, load these reference files:
references/layer-responsibilities.md — Detailed layer responsibilities
references/layer-communication.md — Inter-layer communication patterns
references/dto-patterns.md — Data Transfer Object patterns
references/antipatterns.md — Common violations with detection patterns