Bird
Raised Fist0
PHPprogramming~5 mins

Repository pattern in PHP

Choose your learning style10 modes available
Introduction

The Repository pattern helps you organize how your app talks to data storage. It keeps data access code separate from the rest of your app.

When you want to keep your database code separate from your business logic.
When you plan to switch data sources later without changing your app code.
When you want to write cleaner, easier-to-test code for data access.
When multiple parts of your app need to get or save data in the same way.
When you want to hide complex database queries behind simple methods.
Syntax
PHP
<?php
interface UserRepository {
    public function findById(int $id);
    public function save(User $user);
}

class UserRepositoryImpl implements UserRepository {
    public function findById(int $id) {
        // code to get user from database
    }
    public function save(User $user) {
        // code to save user to database
    }
}

The interface defines what methods the repository must have.

The implementation contains the actual code to get or save data.

Examples
This example shows a repository for products with methods to get all products or find one by name.
PHP
<?php
interface ProductRepository {
    public function findAll();
    public function findByName(string $name);
}

class ProductRepositoryImpl implements ProductRepository {
    public function findAll() {
        // return all products
    }
    public function findByName(string $name) {
        // return product by name
    }
}
This example shows a repository for orders with methods to find orders by user and save an order.
PHP
<?php
interface OrderRepository {
    public function findByUserId(int $userId);
    public function save(Order $order);
}

class OrderRepositoryImpl implements OrderRepository {
    public function findByUserId(int $userId) {
        // get orders for a user
    }
    public function save(Order $order) {
        // save order
    }
}
Sample Program

This program shows a simple User repository using an array to store users. It saves users and finds them by ID.

PHP
<?php
// Simple User class
class User {
    public int $id;
    public string $name;

    public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }
}

// Repository interface
interface UserRepository {
    public function findById(int $id): ?User;
    public function save(User $user): void;
}

// Implementation using an array as data storage
class UserRepositoryImpl implements UserRepository {
    private array $users = [];

    public function findById(int $id): ?User {
        foreach ($this->users as $user) {
            if ($user->id === $id) {
                return $user;
            }
        }
        return null;
    }

    public function save(User $user): void {
        // Replace user if exists, else add
        foreach ($this->users as $index => $existingUser) {
            if ($existingUser->id === $user->id) {
                $this->users[$index] = $user;
                return;
            }
        }
        $this->users[] = $user;
    }
}

// Using the repository
$repo = new UserRepositoryImpl();

// Save some users
$repo->save(new User(1, "Alice"));
$repo->save(new User(2, "Bob"));

// Find user by id
$user = $repo->findById(1);
if ($user !== null) {
    echo "Found user: " . $user->name . "\n";
} else {
    echo "User not found\n";
}

// Try to find a user that does not exist
$user = $repo->findById(3);
if ($user !== null) {
    echo "Found user: " . $user->name . "\n";
} else {
    echo "User not found\n";
}
OutputSuccess
Important Notes

The Repository pattern helps you change the data source later without changing your app code.

Use interfaces to define repository methods so you can swap implementations easily.

Keep repository methods simple and focused on data access only.

Summary

The Repository pattern separates data access from business logic.

It uses interfaces and classes to organize how data is fetched and saved.

This makes your code cleaner, easier to test, and flexible to change.

Practice

(1/5)
1. What is the main purpose of the Repository pattern in PHP?
easy
A. To separate data access logic from business logic
B. To directly connect the database with the user interface
C. To write all code inside a single class
D. To avoid using interfaces in the code

Solution

  1. Step 1: Understand the role of Repository pattern

    The Repository pattern is designed to separate how data is accessed from how the business logic works.
  2. Step 2: Identify the correct purpose

    Separating data access from business logic makes code cleaner and easier to maintain.
  3. Final Answer:

    To separate data access logic from business logic -> Option A
  4. Quick Check:

    Repository pattern = separation of concerns [OK]
Hint: Remember: Repository separates data logic from business logic [OK]
Common Mistakes:
  • Thinking Repository connects UI directly to database
  • Believing all code should be in one class
  • Ignoring the use of interfaces
2. Which of the following is the correct way to declare a Repository interface in PHP?
easy
A. UserRepository interface { public function findUser(int $id); }
B. class UserRepository { public function findUser(int $id); }
C. interface UserRepository { function findUser; }
D. interface UserRepository { public function findUser(int $id); }

Solution

  1. Step 1: Recall PHP interface syntax

    Interfaces use the keyword interface followed by method declarations with parentheses and types.
  2. Step 2: Check each option

    interface UserRepository { public function findUser(int $id); } correctly declares an interface with a method having a typed parameter. class UserRepository { public function findUser(int $id); } uses class instead of interface. interface UserRepository { function findUser; } misses parentheses. UserRepository interface { public function findUser(int $id); } has wrong syntax order.
  3. Final Answer:

    interface UserRepository { public function findUser(int $id); } -> Option D
  4. Quick Check:

    Interface syntax = interface UserRepository { public function findUser(int $id); } [OK]
Hint: Interfaces use 'interface' keyword and method signatures with parentheses [OK]
Common Mistakes:
  • Using 'class' instead of 'interface'
  • Omitting parentheses in method declaration
  • Wrong keyword order in interface declaration
3. Given the following PHP code, what will be the output?
interface UserRepository {
    public function findUser(int $id);
}

class UserRepo implements UserRepository {
    public function findUser(int $id) {
        return "User_" . $id;
    }
}

$repo = new UserRepo();
echo $repo->findUser(5);
medium
A. 5
B. User_5
C. UserRepo
D. Error: Interface method not implemented

Solution

  1. Step 1: Understand interface and class implementation

    The class UserRepo implements UserRepository and defines the method findUser that returns "User_" concatenated with the id.
  2. Step 2: Trace the method call

    Calling $repo->findUser(5) returns "User_5" which is then printed.
  3. Final Answer:

    User_5 -> Option B
  4. Quick Check:

    Method returns 'User_' + id = User_5 [OK]
Hint: Look for string concatenation in method return [OK]
Common Mistakes:
  • Expecting just the number 5 as output
  • Confusing class name with output
  • Thinking interface causes error if implemented correctly
4. Identify the error in this PHP Repository implementation:
interface ProductRepository {
    public function getProduct(int $id);
}

class ProductRepo implements ProductRepository {
    public function getProduct() {
        return "Product";
    }
}
medium
A. Class name should be ProductRepository, not ProductRepo
B. Interface keyword is misspelled
C. Method getProduct() missing parameter in class implementation
D. Return type is missing in interface method

Solution

  1. Step 1: Compare interface and class method signatures

    The interface method getProduct requires an int $id parameter, but the class method has no parameters.
  2. Step 2: Understand PHP interface implementation rules

    When implementing an interface, method signatures must match exactly, including parameters.
  3. Final Answer:

    Method getProduct() missing parameter in class implementation -> Option C
  4. Quick Check:

    Method signatures must match [OK]
Hint: Check method parameters match interface exactly [OK]
Common Mistakes:
  • Ignoring parameter mismatch
  • Thinking class name must match interface name
  • Assuming return type is mandatory in interface
5. You want to create a flexible Repository pattern for managing users and products. Which design approach best supports adding new data types without changing existing code?
hard
A. Create separate interfaces like UserRepository and ProductRepository, then implement them in separate classes
B. Write one big class handling all data types with many methods
C. Use global functions to access data directly
D. Store all data in arrays inside a single class without interfaces

Solution

  1. Step 1: Understand flexibility in Repository pattern

    Using separate interfaces and classes for each data type allows adding new repositories without changing existing ones.
  2. Step 2: Evaluate options for maintainability

    Create separate interfaces like UserRepository and ProductRepository, then implement them in separate classes supports open/closed principle: open for extension, closed for modification. Other options mix concerns or lack structure.
  3. Final Answer:

    Create separate interfaces like UserRepository and ProductRepository, then implement them in separate classes -> Option A
  4. Quick Check:

    Separate interfaces = flexible extension [OK]
Hint: Use separate interfaces and classes for each data type [OK]
Common Mistakes:
  • Putting all logic in one big class
  • Using global functions instead of classes
  • Avoiding interfaces reduces flexibility
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard