HomePHP An Entity Manager for a Unit of Work in PHP
An Entity Manager for a Unit of Work in PHP
In this fifth part of a series, I create a simple entity manager class, which can switch over multiple UoWs by using a single method call. The class will inject into its internals a factory responsible for spawning different UoWs on request. This will permit you to decouple object instantiation from application logic.
Although the model provided by many RDBMS vendors is often the most effective approach to take when performing transactions in several domain objects, it's possible to replicate (at least partially) this functionality at the application level by using a design pattern called Unit of Work (UoW). Implementing this pattern allows you to queue those objects in memory for further insertion, updating and deletion according to the requirements of client code. It also allows you to execute these operations through a single method call, thus optimizing access to the underlying persistence mechanism.
Of course, as with any other pattern, a UoW is language agnostic. This means that it can be implemented in a plethora of programming languages, including PHP. In earlier parts of this series, I proceeded to build an abstract UoW. I even complemented the development process by adding to the UoW a few additional collaborators, such as a MySQL adapter, an abstract data mapper and a class responsible for handling collections of entities.
While at this point it's feasible to create a fully-functional UoW using all of the sample classes defined so far, in this case I'd like to create an extra layer capable of swapping multiple UoWs via a very simple API. As you'll see, the layer will be made up of a basic entity manager class, quite similar to the one present in Doctrine 2.0, but without all its bells and whistles.
Having outlined the goal of this fifth tutorial of the series, it's time to continue learning how to implement a UoW with PHP. Let's jump in!
Review: handling collections of entities
As always, before I start developing the entity manager mentioned above, I'll review the definition of the class created in the previous tutorial. It was a countable iterator charged with manipulating collections of generic entities.
With that said, here's the source code corresponding to this entity iterator. Pay attention to it, please:
/** * Get the entities stored in the collection */ public function getEntities() { return $this->_entities; }
/** * Clear the collection of entities */ public function clear() { $this->_entities = array(); }
/** * Reset the collection of entities (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 from the collection (implementation required by ArrayAccess interface) */ public function offsetGet($key) { return array_key_exists($key, $this->_entities) ? $this->_entities[$key] : null; }
/** * 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); } }
Admittedly, there's much more that can be said about the class above. All it does is implement the methods declared by the Iterator, Countable and ArrayAccess native PHP interfaces to traverse and manipulate generic entities by using an array-like notation. You might think the construction of this class is pointless at first glance, when I build an example that uses the previous UoW, you'll see how helpful it'll be for fetching multiple entities in one go.
But before I reach that point, there are a few things that needs to be done. These include the creation of the entity manager discussed at the beginning. Precisely this topic will be covered in the following segment, so click on the link below and keep reading.