Home arrow PHP arrow Roll Your Own Repository in PHP: Building the Domain Layer

Roll Your Own Repository in PHP: Building the Domain Layer

In this introductory part of a series, I give you an overview of what a repository is and how it can be used for handling collections of domain objects in PHP. Since my goal here is to address the subject from a practical point of view, after I explain some theoretical concepts, I will develop a simple domain layer comprised of two classes. The first one will be an abstract parent that defines the structure and behavior of generic entities, while the second class will be responsible for modeling simple user objects, according to a number of predefined constraints.

TABLE OF CONTENTS:
  1. Roll Your Own Repository in PHP: Building the Domain Layer
  2. Building the domain layer: modeling generic entities
By: Alejandro Gervasio
Rating: starstarstarstarstar / 2
November 17, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Often, during the development of complex PHP applications that expose a rich domain layer, it’s mandatory to decouple the participant domain objects from the underlying persistence layer. In most cases, this underlying layer is a relational database (although it could be a web service or another form of persisting mechanism). In a situation like this, the implementation of data mappers can be of great help to solve the so-called impedance mismatch; they can be used to transparently resolve the internal incompatibilities that exist between both layers, while keeping them isolated from each other.

While data mappers can be thought of as two-way bridges, capable of talking to the persistence layer (AKA data access layer or simply DAL) and of reconstituting domain objects through CRUD operations, they suffer from a well-know drawback. In most of their implementations, those operations tend to be somewhat generic at some point. In relatively simple applications, this shouldn’t be an issue. In more complex scenarios, though, where lots of different domain objects need to be retrieved (beyond the functionality offered by generic finders like “findById()” or “findAll()”), inserted or deleted according to a specific criteria, it’s necessary to build an additional abstraction layer upon the mappers that permits you to execute these operations at a much more narrow level.

That’s exactly where a repository comes into play. It presents an API to client code that allows you to work with collections of related domain objects that match a more refined criteria. Consider, for instance, a user repository where collections of user objects can be fetched from the DAL according to a given role, or a specified name or email address. Put in a simpler way, a repository behaves like a mediator between the existing mappers and the domain layer. It encapsulates, behind a set of discrete methods, all the functionality required to perform specific SQL queries and manipulate collections of domain objects.

Needless to say, the best way to understand the benefits provided by a repository is by example. In line with this concept, in this article series I’m going to recreate the scenario mentioned above by building from scratch a user repository. This repository will be capable of handling collections of user objects that match a given criteria.

Keep in mind that this will be a work in progress -- meaning that before you see the repository finally up and running, you’ll be guided through the creation of the corresponding domain, data access and mapping layers. So, get ready to see a bunch of code samples from this point onward. You’ve been warned.

Now, it’s time to leave the boring theory behind and start rolling a basic repository in PHP. Let’s get started!

Taking the first step: lazy-loading source classes with a basic autoloader

As I noted in the introduction, the progressive development of the user repository will demand that I write a considerable number of source classes, ranging from the ones that will make up the data access and mapping layers, to the ones responsible for creating domain objects (simple users, in this particular case). Since I want to save myself from the hassle of dealing with multiple PHP requires, the first thing that I plan to do will consist of creating a basic autoloader, which will lazy-load the classes though the native autoloading mechanism provided by PHP.

Having clarified that, here’s how this autoloader will be implemented:

(Autoloader.php)

<?php

class Autoloader
{
    private static $_instance;
   
    /**
     * Get the Singleton instance of the autoloader
     */
    public static function getInstance()
    {
        if (self::$_instance === null) {
            self::$_instance = new self;
        }
        return self::$_instance;
    } 
   
    /**
     * Reset the instance of the autoloader
     */
    public static function resetInstance()
    {
        self::$_instance = null;
    }
   
    /**
     * Class constructor
     */
    private function __construct()
    {
        spl_autoload_register(array(__CLASS__, 'load'));
    }
   
    /**
     * Prevent cloning the instance of the autoloader
     */
    private function __clone(){}

    /**
     * Load a given class or interface
     */
    public static function load($class)
    {
        $file = $class . '.php';
        if (!file_exists($file)) {
            throw new ClassNotFoundException('The file containing the requested class ' . $class . 'or interface was not found.');
        }
        require $file;
        if (!class_exists($class, false) && !interface_exists($class, false)) {
            throw new ClassNotFoundException('The requested class or interface ' . $class . ' was not found.');
        }
    }  
}

 

(ClassNotFoundException.php)

<?php

class ClassNotFoundException extends Exception{}

As shown in the above code fragment, the autoloader is nothing but a simple Singleton, which loads classes on demand by using the SPL stack, and also throws a couple of custom exceptions when the process fails for some typical reasons. To keep things pretty clear and understandable, this class doesn’t take advantage of native or user-defined namespaces, but if you need to implement this feature (or others), feel free to do so.  

So far, so good. Having already built a basic autoloader that lazy-loads resources, it’s time to start creating the classes that will comprise the domain layer of this example. The first of these classes will be an abstract parent. It will be tasked with modeling generic entities via the complementary “__set()” and “__get()” PHP magic methods.

To see how this abstract class will be defined, click on the link below and read the following segment.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: