Home arrow PHP arrow PHP Proxy Patterns: Collections and Classes

PHP Proxy Patterns: Collections and Classes

In this second part of a three-part tutorial, I add to the existing structure of our sample blog program a host of useful components. These include the classes that handle collections of entities and views, and most importantly, the ones responsible for lazy-loading domain objects from the database.

TABLE OF CONTENTS:
  1. PHP Proxy Patterns: Collections and Classes
  2. Building
By: Alejandro Gervasio
Rating: starstarstarstarstar / 0
October 24, 2011

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Although they still haven’t gained the huge level of popularity of other design patterns (at least in the PHP field), proxies are a powerful paradigm that allows users to perform some clever tasks in OOP. These include unit testing classes, introspecting other objects, and even implementing more efficient data persistence strategies (pretty similar to what Doctrine 2.x does behind the scenes with entities).

Of course, talking about the virtues that proxy objects offer without backing up the words with code samples is pointless. Therefore, in the introductory part of this tutorial, I started developing an extendable blog application. It took advantage of the functionality of a proxy class to lazy-load, from a MySQL database, the comments associated to a given blog entry.

Well, to be frank, so far I've demonstrated how an instance of the proxy class can be used to fill the “comments” field of each entry. If you’re anything like me, however, you want to see the actual implementation of this class, along with a few others, which comprise the blog. Fear not; in this second installment, I’ll be building all of these remaining classes, so that you can see more clearly how they fit into the blog’s existing structure.

Ready to learn how the use of proxy objects can optimize the persistence of a domain model? Then don’t hesitate anymore; read the lines to come!

Adding more functionality to the blog: handling collections of entities

As I noted in the introduction, it’s necessary to build some additional classes (including the proxies) to make the blog program entirely functional. The first class I plan to show you handles collections of entities, which allows for easy iteration over multiple entries, as well as over the comments related to a particular blog entry.   

Below I listed for you the interface implemented by this class, followed by the class itself. Check them out:

(MyApp/Common/CollectionInterface.php)

<?php

namespace MyApp\Common;
use MyApp\Model;

interface CollectionInterface extends \Countable, \IteratorAggregate, \ArrayAccess
{
    public function toArray();

    public function clear();

    public function reset();

    public function add($key, Model\AbstractEntity $entity);
   
    public function get($key);

    public function remove($key);

    public function exists($key);
}

 

(MyApp/Common/EntityCollection.php)

<?php

namespace MyApp\Common;
use MyApp\Model;

class EntityCollection implements CollectionInterface
{
    protected $_entities = array();

    /**
     * Constructor
     */
    public function __construct(array $entities = array())
    {
        $this->_entities = $entities;
        $this->reset();
    }

    /**
     * Get the entities stored in the collection
     */
    public function toArray()
    {
        return $this->_entities;
    }

    /**
     * Clear the collection
     */
    public function clear()
    {
        $this->_entities = array();
    }
    
    /**
     * Rewind the collection
     */    
    public function reset()
    {
        reset($this->_entities);
    }

    /**
     * Add an entity to the collection
     */
    public function add($key, Model\AbstractEntity $entity) {
        return $this->offsetSet($key, $entity);
    }

    /**
     * Get from the collection the entity with the specified key
     */
    public function get($key)
    {
        return $this->offsetGet($key);
    }

    /**
     * Remove from the collection the entity with the specified key
     */
    public function remove($key)
    {
        return $this->offsetUnset($key);
    }

    /**
     * Check if the entity with the specfied key exists in the collection
     */
    public function exists($key)
    {
        return $this->offsetExists($key);
    }

    /**
     * Count the number of entities in the collection
     */
    public function count()
    {
        return count($this->_entities);
    }

    /**
     * Get the external array iterator
     */
    public function getIterator()
    {
        return new \ArrayIterator($this->toArray());
    }

    /**
     * Add an entity to the collection
     */
    public function offsetSet($key, $entity)
    {
        if (!$entity instanceof Model\AbstractEntity) {
            throw new \InvalidArgumentException('To add an entity to the collection, it must be an instance of EntityAbstract.');
        }
        if (!isset($key)) {
            $this->_entities[] = $entity;
        }
        else {
            $this->_entities[$key] = $entity;
        }
        return true;
    }
   
    /**
     * Remove an entity from the collection
     */
    public function offsetUnset($key)
    {
        if ($key instanceof Model\AbstractEntity) {
            $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
     */
    public function offsetGet($key)
    {
        return isset($this->_entities[$key])
            ? $this->_entities[$key] : null;
    } 
   
    /**
     * Check if the specified entity exists in the collection
     */    
    public function offsetExists($key)
    {
        return isset($this->_entities[$key]);
    }
}

Leaving aside the contract defined by the “CollectionInterface” interface, which is easy to grasp, you should focus your attention on its implementer “EntityCollection.” As you can see, this class is nothing but an iteratable and countable array collection. It allows you to manipulate groups of entities in a straightforward fashion. Its driving logic is as simple as that.    

In a typical use case, this class should be utilized for traversing the comments related to a specific blog entry, or even for processing its related comments. However, this would imply that each time that we fetched an entry from the database, we would have to fetch the comments, too. In short, we might end up pulling out the entire database… yes, unnecessarily.

As I noted at the start, this issue can be addressed by using a proxy that acts like a mediator for the actual entity collection, which internally knows how to fetch the comments from the storage on request. Thus, in the next section I’ll be showing you the definition of this proxy class, so that you can understand how it works.  

Now, click on the link below and keep reading.



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