Home arrow PHP arrow Page 2 - PHP Service Layers: Handling Entity Collections

Building a generic array collection class - PHP

In this fourth part of the series, I add to the mapping layer of this sample application a couple of additional classes. These new classes will handle collections of entities (and more specifically, user objects).

TABLE OF CONTENTS:
  1. PHP Service Layers: Handling Entity Collections
  2. Building a generic array collection class
By: Alejandro Gervasio
Rating: starstarstarstarstar / 0
October 17, 2011

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

As I noted in the prior segment, it's necessary to create a pair of classes capable of traversing and accessing collections of entities, so they can be used internally by the "findAll()" and "search()" methods implemented by the previous data mappers.

The following class performs these tasks in a simple fashion. Look at it:

(MyApplication/Collection/AbstractCollection.php)

<?php

namespace MyApplicationCollection;

abstract class AbstractCollection implements Iterator, Countable, ArrayAccess
{
    protected $_entities = array();
    protected $_entityClass;

    /**
     * Constructor
     */
    public function  __construct(array $entities = array())
    {
        if (!empty($entities)) {
            $this->_entities = $entities;
        }
        $this->rewind();
    }

    /**
     * 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're more entities in the collection (implementation required by Iterator Interface)
     */
    public function valid()
    {
        return ($this->current() !== false);
    }
   
    /**
     * 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 ($entity instanceof $this->_entityClass) {
            if (!isset($key)) {
                $this->_entities[] = $entity;
            }
            else {
                $this->_entities[$key] = $entity;
            }
            return true;
        }
        throw new CollectionException('The specified entity is not allowed for this collection.');
    }
   
    /**
     * Remove an entity from the collection (implementation required by ArrayAccess interface)
     */
    public function offsetUnset($key)
    {
        if ($key instanceof $this->_entityClass) {
            $this->_entities = array_filter($this->_entities, function ($v) use ($key) {
                return $v !== $key;
            });
            return true;
        }
        if (isset($this->_entities[$key])) {
            unset($this->_entities[$key]);
            return true;
        }
        return false;
    }
   
    /**
     * Get the specified entity in the collection (implementation required by ArrayAccess interface)
     */
    public function offsetGet($key)
    {
        return isset($this->_entities[$key]) ?
               $this->_entities[$key] :
               null;
    } 
   
    /**
     * Check if the specified entity exists in the collection (implementation required by ArrayAccess interface)
     */    
    public function offsetExists($key)
    {
        return isset($this->_entities[$key]);
    }
}

 

(MyApplication/Collection/CollectionException.php)

<?php

namespace MyApplicationCollection;

class CollectionException extends Exception{}

The "AbstractCollection" class is nothing but a simple wrapper for a plain PHP array. This class encapsulates the functionality required for iterating over its elements, as well as for counting and accessing them, thanks to the implementation of the Iterator, Countable and ArrayAccess SPL interfaces.

While this abstract class does a good job of handling collections of generic entities, in this case it's mandatory to spawn a concrete subclass that allows it to specifically handle user objects. Remember, our final goal is to implement a user service.

Don't worry, however, because this derivative will be shown in the following segment. So keep reading. 

Taking the final step: developing a user collection class

If you think that implementing a concrete class responsible for traversing collections of user entities is difficult, the following code bit should make you change your mind. Check it out:

(MyApplication/Collection/UserCollection.php)

<?php

namespace MyApplicationCollection;

class UserCollection extends AbstractCollection
{
    protected $_entityClass = 'MyApplicationEntityUser';

  
That was really easy to code and read, right? As you can see, the creation of a child class that works with a specified type of domain object is reduced to overriding the abstract parent's $_entityClass field and nothing else. Period.

With these two collection handling classes living in sweet harmony, we've taken a big step toward the implementation of a functional user service.

Final Thoughts

In this fourth part of the series, I added a couple of additional classes to the mapping layer of this sample application. They're charged with handling collections of entities (and more specifically, user objects).

With the inclusion of these classes, at this point the application is functional (assuming that the corresponding MySQL database has been previously created). What's more, it's really easy to set up a domain model with a few user entities in it, then build a mapper and finally start putting data into, and pulling it out of, the storage area. 

But, what does this buy us, if what we're trying to implement here is a user service, not a user mapper (which is already done)? Well, leave your concerns behind, because in the upcoming tutorial I'll be defining the service, so that you can finally see how it fits into the current application schema.

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: