While I have to admit that I’m not a big fan of creating classes that rely too much on the magic methods bundled with PHP, in this case I’m going to implement an approach similar to the one proposed by Ben Scholzen and use the complementary “__set()”/“__get()” pair to construct the abstract parent mentioned in the previous segment. This class will be responsible for defining the structure and behavior of generic entities (like users, blog posts and so forth), and its source code is shown below: (EntityAbstract.php) <?php abstract class EntityAbstract
(EntityException.php) <?php class EntityException extends Exception {} As you can see above, the “EntityAbstract” class accepts, through its constructor, an associative array of data. This data is used to assign, all at once, a set of values to its undeclared fields. This process is carried out via the “__set()” method, which first attempts to perform the assignment process via the corresponding mutator; if this method doesn’t exist, the value is assigned directly through the protected "$_values” array. A similar logic is also implemented within the counterpart “__get()”, even though in this case the method checks to see if the value assigned to the specified field can be retrieved by means of a getter. In addition, the class declares a property called $_allowedFields, which is used to restrict the fields that can be assigned to the entity. Now, do you understand the logic of this generic parent? Good. Having already defined an abstract class that encapsulates the logic shared by generic entities, the next step in the development of the sample user repository is to derive a subclass capable of modeling user objects, so that they can be properly handled afterward by their associated mapper and, at an upper level, by the repository. This new child class will be built in the next section below, so keep reading. To be frank, building a class that models user objects is a straightforward process, since most of its logic has already been implemented by its abstract parent. In this specific case, and for the sake of brevity, any user object spawned from this class will be allowed to have only four fields: an ID, then a first and a last name, and finally an email address. With those constraints properly outlined, here’s the definition of this concrete class, not surprisingly called “User”: (User.php) <?php class User extends EntityAbstract I'm sure you’ll agree that the “User” class shown above is a breeze to follow. All it does is implement a bunch of mutators corresponding to each of its allowed fields. These methods impose some basic restrictions to the values assigned to the pertinent properties; it’s possible, however, to perform a more strict validation, either by using procedural code or through a set of injected validation objects. Finally, to keep things short and simple I decided not to define any getters. This means that the values assigned to the fields of the class will be directly retrieved from the internal $_values array. Nevertheless, if you want to tackle this extra work on your own and implement these complementary methods, feel free to do so. And with the inclusion of this concrete user-modeling class, the first step toward the construction of the user repository is now complete. Bear in mind that this is only the beginning of a long and hopefully instructive journey, so for the moment be patient. Final thoughts In this introductory part of the series, I provided you with 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 explaining some theoretical concepts, I went through the development of a simple domain layer comprised of two classes. The first one was an abstract parent that defined the structure and behavior of generic entities, while the second class was responsible for modeling simple user objects, according to a number of predefined constraints. Considering that a repository usually resides between the domain and mapping layers of an application, and the latter also accesses in turn the data access layer, in the next tutorial I’m going to create this last layer, which in this case will be tasked with talking to MySQL. Don’t miss the upcoming part!
blog comments powered by Disqus |
|
|
|
|
|
|
|