Roll Your Own Repository in PHP: a More Functional User Repository

In this penultimate installment of the series, I extend the functionality of the user repository created in the previous part by adding two methods to it. These methods will handle adding new user entities to the underlying MySQL database and removing existing ones. Their implementation, as you’ll see, will be a fairly straightforward process.

If you’re a PHP developer interested in expanding your current background in design patterns, and you want more intimate knowledge of building a repository from scratch, then this is the article series for you. Over the course of its eight tutorials, you’ll be guided through the development of a sample web application, whose main area of responsibility will be to query collections of user entities via a simple, yet functional repository class.

And now that you’ve been introduced to the series’ primary goal, it’s time to review the topics covered in the last installment. In that part I defined the initial implementation of the aforementioned repository. This implementation could retrieve, from the underlying MySQL database, collections of user objects that matched some specified criteria. In addition, I defined a basic factory class that allowed you to hide from client code all the complexities involved in the creation of the repository. This process helped to isolate the object instantiation from the application’s logic.

It’s valid to note, however, that this sample user repository still isn’t capable of inserting and deleting user entities from the persistence layer, so its current functionality is somewhat limited. In this penultimate part of the series, however, I’m going to add to the repository class a couple of simple methods that will be tasked with performing the insertions and deletions in a fairly simple way.

Do you want to learn how these additional methods will be defined? Then jump ahead and read the following lines!

Review: the current user repository class

Since I intend to extend the functionality of the user repository class created in the previous part of the series, it’d be instructive to recall the initial definition of this class. You’ll see how it can be used for fetching collections of user entities through a set of intuitive methods.

With that said, here’s the partial definition of this sample repository. Right now it’s only able to retrieve user entities according to a given first and last name, and by specifying an email address:

(UserRepository.php)

<?php

class UserRepository
{
    protected $_userMapper;
   
    /**
     * Class constructor
     */
    public function __construct(UserMapper $userMapper)
    {
        $this->_userMapper = $userMapper;   
    }
   
    /**
     * find users by their first names
     */
    public function findByFirstName($fname)
    {
        return $this->_userMapper->search("fname = ‘$fname’");
    }
   
    /**
     * find users by their last names
     */
    public function findByLastName($lname)
    {
        return $this->_userMapper->search("lname = ‘$lname’");
    }
   
    /**
     * find users by their email addresses
     */
    public function findByEmail($email)
    {
        return $this->_userMapper->search("email = ‘$email’");
    }
}

If you ever thought that the construction of a repository class was a challenging process, the above code sample should change your mind quickly. As you can see, the only dependency injected into the internals of this class is an instance of the user mapper. This is used internally for each finder, to retrieve collections of user entities that match some basic conditions.

Since the creation of this repository requires the instantiation of all of its collaborators, I decided to hide the complexities of this process inside a factory. Its definition looks like this:    

(RepositoryFactory.php)

<?php

class RepositoryFactory
{
    /**
     * Create a repository based on the given name
     */
    public function create($name, array $options = array())
    {
        $name = ucfirst(strtolower($name));
        $adapter    = MySQLAdapter::getInstance();
        $collection = $name . ‘Collection';
        $mapper     = $name . ‘Mapper';
        $repository = $name . ‘Repository';
        return new $repository(
            new $mapper($adapter, new $collection, $options));
    } 
}

Effectively, the above factory does the hard work and takes care of correctly instantiating different kinds of repositories, including the one that works with user entities. Since this class behaves like a simple  dependency injection container, it’s time to provide the user repository with the ability to add and delete user objects.

As I stated in the introduction, this extended functionality will be implemented through a few additional methods. These methods will be discussed in depth in the following section. Thus, to learn more about how these methods will be defined, click on the link below and read the lines to come.

{mospagebreak title=Adding and removing user entities}

To be frank, creating a set of methods that allow you to insert new user entities into their associated MySQL table, and to delete them as well, is an extremely simple procedure, thanks to the level of abstraction exposed by the earlier repository class. If you still aren’t sure of how to implement such methods, I suggest you look at the following code fragment:

/**
 * Insert a new user
 */
public function insert(User $user)
{
    $this->_userMapper->insert($user);
}

/**
 * Delete an existing user
 */
public function delete($id)
{
    $this->_userMapper->delete($id);
}

Didn’t I just tell you that adding new user entities to the persistence layer and removing them from it was actually a no-brainer process? Well, as the above code snippets show, these tasks are performed by two separate methods, not surprisingly called “insert()” and “delete(),” respectively.

What’s more, the implementation of these methods demonstrates how easy it is to concentrate query code within an application by using a single repository. For the sake of brevity I decided to provide this sample repository with the ability to fetch collections of user entities that match a specified first and last name, and an email address as well. It’s feasible, however, to encapsulate more complex queries behind additional discrete methods, so if you feel adventurous and want to tackle this on your own, go ahead and start tweaking the user repository. It’ll be fun, trust me.

And now that you’ve grasped the logic driving the methods just defined, it’s time to add them to the source code of the user repository. In doing so, you’ll be able to see how this class looks when it is finished.

This will be done below.   

The finished user repository            

If you want to see how the sample user repository looks after adding the additional methods discussed above to it, below I included the full source code of this class, so that you can analyze it and catch its underlying logic. Here it is:

(UserRepository.php)

<?php

class UserRepository
{
    protected $_userMapper;
   
    /**
     * Class constructor
     */
    public function __construct(UserMapper $userMapper)
    {
        $this->_userMapper = $userMapper;   
    }
   
    /**
     * find users by their first names
     */
    public function findByFirstName($fname)
    {
        return $this->_userMapper->search("fname = ‘$fname’");
    }
   
    /**
     * find users by their last names
     */
    public function findByLastName($lname)
    {
        return $this->_userMapper->search("lname = ‘$lname’");
    }
   
    /**
     * find users by their email addresses
     */
    public function findByEmail($email)
    {
        return $this->_userMapper->search("email = ‘$email’");
    }
   
    /**
     * Insert a new user
     */
    public function insert(User $user)
    {
        $this->_userMapper->insert($user);
    }
   
    /**
     * Delete an existing user
     */
    public function delete($id)
    {
        $this->_userMapper->delete($id);
    }            
}

Mission accomplished. Even though so far, you haven’t seen a specific example that shows how to utilize the previous “UserRepository” class (along with its corresponding dependencies, of course) in a truly useful fashion, at this point you must have a clearer idea of its real functionality. Bear with me and wait until the next tutorial, where you’ll be able to see how to use this class to manipulate collections of user entities in a few easy steps.

Final thoughts

That’s all for the moment. In this penultimate installment of the series, I extended the functionality of the previous user repository a little further by adding two methods to it, which were tasked with adding new user entities to the underlying MySQL database and removing existing ones. As you just saw, the implementation of these additional methods was a fairly straightforward process, so in theory you shouldn’t have major problems understanding how they do their business.

Now that the development of this sample repository has been completed, the next logical step is to put it to work, so you can see for yourself how functional it can be when used in a concrete case. Therefore, in the last part of the series, I’m going to create an example that will show how to easily query collections of user entities by means of the repository.

Here’s my final piece of advice: don’t miss the conclusion to this series!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan