Proper Repository Pattern Design in PHP?

The Repository pattern in PHP is a design pattern that allows for the separation of the business logic of an application from the storage and retrieval of data. The pattern involves creating a Repository class that acts as an intermediary between the business logic and the data storage.

Watch a course Learn object oriented PHP

Here are some key principles to follow when designing a Repository pattern in PHP:

  1. The Repository class should only be responsible for interacting with the data storage, such as a database or an API.

  2. The Repository class should not contain any business logic.

  3. The Repository class should provide a consistent and easy-to-use interface for the rest of the application to interact with the data storage.

  4. The Repository class should be easy to test, by allowing to swap out the data storage with a test double such as a mock or a stub.

  5. The Repository class should be decoupled from the specific data storage technology used, so that it can be easily swapped out with a different one.

  6. Use interfaces to define the expected methods and types of the repository.

  7. Use Dependency injection to pass the repository class to the classes that need it.

An example of a simple repository pattern in PHP would be:

<?php

interface RepositoryInterface
{
  public function getById($id);
  public function getAll();
  public function save($data);
}

class Repository implements RepositoryInterface
{
  protected $db;
  public function __construct($db)
  {
    $this->db = $db;
  }
  public function getById($id)
  {
    // mock implementation to return data
    return ['id' => $id, 'name' => 'Product ' . $id, 'price' => 100.0];
  }
  public function getAll()
  {
    // mock implementation to return all data
    return [['id' => 1, 'name' => 'Product 1', 'price' => 100.0], ['id' => 2, 'name' => 'Product 2', 'price' => 200.0], ['id' => 3, 'name' => 'Product 3', 'price' => 300.0]];
  }
  public function save($data)
  {
    // mock implementation to save data
    echo "Saving data: " . print_r($data, true) . "\n";
  }
}

$repository = new Repository(null);

$productId = 1;
$product = $repository->getById($productId);

echo "Product Information: ";
echo "ID: " . $product['id'] . "\n";
echo "Name: " . $product['name'] . "\n";
echo "Price: " . $product['price'] . "\n";

$allProducts = $repository->getAll();
echo "All Products: \n";
foreach ($allProducts as $p) {
  echo "ID: " . $p['id'] . "\n";
  echo "Name: " . $p['name'] . "\n";
  echo "Price: " . $p['price'] . "\n";
}

$newProduct = ['name' => 'Super Product', 'price' => 99.99];
$repository->save($newProduct);
echo "New product saved successfully!\n";

?>

This is just an example and you can add or remove methods as per your requirements.