Home arrow PHP arrow Page 2 - Roll Your Own Repository in PHP: Working with Collections of Entities

Manipulating collections of entities with an abstract collection class - PHP

In this fifth part of the series, I add two additional classes to our sample PHP application. They will be responsible for handling collections of generic entities, and more specifically, collections of user objects. In truth, these new classes will be simple countable iterators, capable of accessing the entities as if they were array elements.

TABLE OF CONTENTS:
  1. Roll Your Own Repository in PHP: Working with Collections of Entities
  2. Manipulating collections of entities with an abstract collection class
By: Alejandro Gervasio
Rating: starstarstarstarstar / 3
December 07, 2010

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

I don't want to sound like a braggart, believe me. But creating a class capable of manipulating collections of entities is a straightforward process. Basically, the entire process of creation is reduced to building a countable iterator that can access those entities as if they were plain array elements. It's that simple, really.

To clarify this concept a bit further, take a look at the class below, which performs all of these tasks with generic entities:  

(CollectionAbstract.php)

<?php

abstract class CollectionAbstract implements Iterator, Countable, ArrayAccess
{
    protected $_entities = array();
   
    /**
     * Get the entities stored in the collection
     */
    public function getEntities()
    {
        return $this->_entities;
    }
   
    /**
     * Clear the collection
     */
    public function clear()
    {
        $this->_entities = array();
    }
    
    /**
     * Reset the collection (implementation required by Iterator Interface)
     */    
    public function rewind()
    {
        reset($this->_entities);
    }
   
    /**
     * Get the current entity in the collection (implementation required by Iterator Interface)
     */
    public function current()
    {
        return current($this->_entities);
    }
   
    /**
     * Move to the next entity in the collection (implementation required by Iterator Interface)
     */
    public function next()
    {
        next($this->_entities);
    }
   
    /**
     * Get the key of the current entity in the collection (implementation required by Iterator Interface)
     */
    public function key()
    {
        return key($this->_entities);
    }
   
    /**
     * Check if there are more entities in the collection (implementation required by Iterator Interface)
     */
    public function valid()
    {
        return (boolean) $this->current();
    }
   
    /**
     * Count the number of entities in the collection (implementation required by Countable Interface)
     */
    public function count()
    {
        return count($this->_entities);
    }
   
    /**
     * Add an entity to the collection (implementation required by ArrayAccess interface)
     */
    public function offsetSet($key, $entity)
    {
        if ($key === null) {
            if (!in_array($key, $this->_entities, true)) {
                $this->_entities[] = $entity;
                return;
            }
        }
        else if (!array_key_exists($key, $this->_entities)) {
            $this->_entities[$key] = $entity;
        }
    }
   
    /**
     * Remove an entity from the collection (implementation required by ArrayAccess interface)
     */
    public function offsetUnset($key)
    {
        if ($key instanceof EntityAbstract) {
            $entities = array();
            foreach ($this->_entities as $_entity) {
                if ($_entity !== $key) {
                    $entities[] = $_entity;
                }  
            }
            $this->_entities = $entities;
            return;
        }
        if (array_key_exists($key, $this->_entities)) {
            unset($this->_entities[$key]);
        }
    }
   
    /**
     * Get the specified entity in the collection (implementation required by ArrayAccess interface)
     */
    public function offsetGet($key)
    {
        if (array_key_exists($key, $this->_entities)) {
            return $this->_entities[$key];
        }
    } 
   
    /**
     * Check if the specified entity exists in the collection (implementation required by ArrayAccess interface)
     */    
    public function offsetExists($key)
    {
        return array_key_exists($key, $this->_entities);
    }
}

As the above code snippet shows, the previous "CollectionAbstract" class encapsulates most of the functionality required for handling collections of generic entities in a fairly simple way. In this case, I decided to make the class an implementer of the Countable, Iterator and ArrayAccess PHP native interfaces, but similar results can be obtained with other iteratable interfaces as well.

So far, so good. Having created an abstract parent capable of working with generic entities, the next step is to derive a subclass that deals specifically with collections of user objects. Again, I have to say this process is a breeze to accomplish. However, the best way to demonstrate this is by showing the full source code of this child class. 

This will be done below, so keep reading.

Working with a collection of user entities: a refined implementation of the earlier collection class

Considering that the primary goal of a user repository is to query collections of user entities, it's necessary to build a class capable of performing that task in a simple manner. Since the abstract parent defined in the preceding segment does most of the hard work and handles collections of generic entities, creating a refined implementation that deals only with user objects is as easy as defining the following subclass: 

(UserCollection.php)

<?php

class UserCollection extends CollectionAbstract
{
    /**
     * Add a user to the collection
     */
    public function add($key, User $user)
    {
        $this->offsetSet($key, $user);
    }     
}

That was truly easy to code, right? As its name implies, the only area of responsibility of the previous "UserCollection" class is to manipulate collections of user entities, which has been achieved in this case by implementing an additional method that adds user objects to the internal collection. This is nothing but Inheritance 101, but the existence of these two collection classes now permits us to see in a clearer way how they can be put to work side by side with the other classes defined in earlier tutorials to create a functional user repository.

But I'm getting ahead of myself, as every detail of this process will be covered in the next installment.    

Final thoughts

In this fifth installment of the series, I added to this sample PHP application a couple of additional classes, responsible for handling collections of generic entities -- and more specifically, collections of user objects. As you just saw, the logic implemented by these classes was pretty easy to catch, as they're nothing but simple countable iterators, capable of accessing the mentioned entities as if they were array elements.

With these iterators up and running, the scenario is finally set to start building the desired user repository. Nevertheless, the inner workings of this process will be discussed in depth in the forthcoming tutorial. So don't miss the next part!



 
 
>>> 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: