Data Mapper Architecture
The Data Mapper pattern separates your domain objects from database persistence. Entities contain business logic and data, while a separate mapper layer — the EntityManager — handles storage and retrieval.
How It Works
The Data Mapper pattern splits persistence into two parts: entities that hold data and business logic, and an EntityManager that handles all database operations. The entity and the database never talk to each other directly. An entity is just a plain PHP class:
<?php
class ProductEntity {
private ?int $productId = null;
private string $name;
private float $price;
// Business logic lives here
public function applyDiscount(float $percent): void {
$this->price = $this->price * (1 - $percent / 100);
}
// Getters and setters
public function getProductId(): ?int { return $this->productId; }
public function getName(): string { return $this->name; }
public function setName(string $name): void { $this->name = $name; }
public function getPrice(): float { return $this->price; }
public function setPrice(float $price): void { $this->price = $price; }
}
Database operations go through the EntityManager:
<?php
$entityManager = new EntityManager($connection, $config);
// Creating
$product = new ProductEntity();
$product->setName('Wireless Mouse');
$product->setPrice(29.99);
$entityManager->persist($product);
$entityManager->flush();
// Updating
$product = $entityManager->find(ProductEntity::class, 123);
$product->applyDiscount(10);
$entityManager->persist($product);
$entityManager->flush();
The entity never knows it's being stored. It doesn't know what database it lives in, what table it maps to at runtime, or when it gets saved. The EntityManager owns that responsibility entirely.