#StackBounty: #php #design-patterns #orm #repository #datamapper Why bother with repositories

Bounty: 50

I feel a bit stupid asking this question since there are a lot of resources talking and explaining mappers and repositories but I can’t seem to get my head around it. So I’ve created some example code to explain my confusion. Please note that I don’t know if this code would actually work I wrote this as an example.

This would be the entity / class (Quote.php)

class Quote {
  private $id;
  private $author;
  private $content;

  public function getId() {
    return $this->id;
  }

  public function getAuthor() {
    return $this->author;
  }

  public function getContent() {
    return $this->content;
  }

  public function setId(int $id) {
    $this->id = $id;
  }

  public function getAuthor(string $author) {
    $this->author = $author;
  }

  public function setContent(string $content) {
    $this->content = $content;
  }
}

And this would be the mapper (QuoteMapper.php)

class QuoteMapper {
  private $PDO;

  public function __construct(PDO $PDO) {
    $this->PDO = $PDO;
  }

  public function find(int $id = null, string $search = null) {
    if (!empty($id) && !empty($search)) {
      //Search for id and search word
      $stmt = $this->PDO->prepare("SELECT `id`, `author`, `content` FROM `quotes` WHERE `id` = :id AND `content` LIKE :search LIMIT 1");
      $stmt->bindParam('search', $search, PDO::PARAM_INT);
      $stmt->bindParam('id', $id, PDO::PARAM_INT);
    else if (!empty($id)) {
      //search for id only
      $stmt = $this->PDO->prepare("SELECT `id`, `author`, `content` FROM `quotes` WHERE `id` = :id AND `content` LIKE :search LIMIT 1");
      $stmt->bindParam('id', $id, PDO::PARAM_INT);
    } else if (!empty($search)) {
      //search for search word only
      $stmt = $this->PDO->prepare("SELECT `id`, `author`, `content` FROM `quotes` WHERE `id` = :id AND `content` LIKE :search LIMIT 1");
      $stmt->bindParam('search', $search, PDO::PARAM_INT);
    }

    $stmt->execute();

    $stmt->bindColumn('id', $id);
    $stmt->bindColumn('author', $author);
    $stmt->bindColumn('content', $content);
    $stmt->fetch();

    $quote = new Image();
    $quote->setId($title);
    $quote->setAuthor($source);
    $quote->setContent($alternative);

    return $image;
  }

  public function save(Quote $quote) {
    //A save function
  }

  public function delete(Quote $quote) {
    //A delete function
  }
}

Last but not least, this would be the repository (QuoteRepository.php)

class ArticleRepository {
  private $articleMapper;

  public function __construct(ArticleMapper $articleMapper) {
    $this->articleMapper = $articleMapper;
  }

  public function find(int $id = null, string $search = null) {
    $article = $this->articleMapper->find($id, $search);
    return $article;
  }

  public function save(Quote $quote) {
    $this->articleMapper->save($user);
  }

  public function delete(Quote $quote) {
    $this->articleMapper->delete($user);
  }
}

As I understand my mapper isn’t ‘wrong’ since the purpose of the mapper is to do things such as get and set data from persistent data storage (such as MySQL)

A Data Mapper is a Data Access Layer that performs bidirectional
transfer of data between a persistent data store (often a relational
database) and an in-memory data representation (the domain layer).
From Wikipedia

But my repository doesn’t actually do anything. It just passes the function call along to the mapper? So I can only assume that my mapper contains code that should be in the repository, but what code would that be? Or perhaps I’ve completely misunderstood how data mappers and repositories would work together.

If there are any other things that I have done that are wrong or considered bad practice I would like to hear it. I’m really trying to figure this out! 🙂


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.