Home arrow PHP arrow Page 2 - PHP Service Layers: User Services

Building an abstract service - PHP

In this fifth installment of the series, I will finally implement a fully functional user service. This additional layer will use the functionality of a mapper to run CRUD functions on user entities, as well as retrieve these domain objects in XML format.

TABLE OF CONTENTS:
  1. PHP Service Layers: User Services
  2. Building an abstract service
By: Alejandro Gervasio
Rating: starstarstarstarstar / 0
October 17, 2011

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Despite this rather intimidating definition, building a service layer is a straightforward process. Don't believe me? Focus your attention on the following class, which implements a service that works with generic entities: 

(MyApplication/Service/AbstractService.php)

<?php

namespace MyApplicationService;
use MyApplicationMapper,
    MyApplicationEntity;

abstract class AbstractService
{
    protected $_mapper;

    /**
     * Constructor
     */
    public function  __construct(MapperAbstractDataMapper $mapper)
    {
        $this->_mapper = $mapper;
    }

    /**
     * Find an entity by their ID
     */
    public function findById($id)
    {
        return $this->_mapper->findById($id);
    }

    /**
     * Find all the entities
     */
    public function findAll()
    {
        return $this->_mapper->findAll();
    }

    /**
     * Insert a new entity
     */
    public function insert(EntityEntityAbstract $entity)
    {
        return $this->_mapper->insert($entity);
    }

    /**
     * Update an entity
     */
    public function update(EntityEntityAbstract $entity)
    {
        return $this->_mapper->update($entity);
    }

    /**
     * Delete an entity
     */
    public function delete($id)
    {
        return $this->_mapper->delete($id);
    }
}

As seen above, thanks to the ďcleverĒ (if thatís really the appropriate term) use of dependency injection, constructing an abstract service that runs CRUD operations on a few domain objects is a breeze. At first glance, the implementation of this additional abstraction layer seems to be somewhat redundant, especially when compared with the functionality already offered by the mapping layer -- but this is a misleading impression, trust me.

In this case, the applicationís concerns are quite trivial, reduced to fetching, saving and deleting entities from the database. But what if itís necessary to do many other things, like interfacing with a different front-end, sending a newsletter or retrieving aggregated roots, like blog posts and their associated comments? Are we going to pollute our action controllers with all that stuff and suffer the side effects of code duplication nearly everywhere? That sounds lame, indeed.    

Undeniably, the best way to encapsulate all of this logic is behind a service layer. In the following segment Iíll be creating a user service, which naturally will be a derivative of the previous abstract parent.

Now, move ahead and read the lines to come.

Refining the earlier abstract parent class: implementing a user service

Since the abstract service defined earlier already implements the logic required to run CRUD functions on generic entities, creating a subclass that works specifically with user objects is a straightforward process that can be accomplished in a few easy steps.

If you still wonder how this user service will look, pay attention to the following class: 

(MyApplication/Service/UserService.php)

<?php

namespace MyApplicationService;
use MyApplicationMapper,
    MyApplicationEntity;

class UserService extends AbstractService
{
    /**
     * Constructor
     */
    public function  __construct(MapperUserMapper $mapper)
    {
        parent::__construct($mapper);
    }

    /**
     * Save a user to persistence layer
     */
    public function save(EntityUser $user)
    {
        return $user->id === null ?
               $this->insert($user) :
               $this->update($user);
    }

    /**
     * Fetch all users in XML format
     */
    public function toXML()
    {
        $users = $this->_mapper->findAll();
        $xml = "<?xml version="1.0" encoding="UTF-8"?>n<users>n";
        foreach($users as $user) {
            $xml .= "<user>n<fname>$user->fname</fname>n"
                  . "<lname>$user->lname</lname>n"
                  . "<email>$user->fname</email>n</user>n";
        }
        $xml .= "</users>";
        return $xml;
    }
}

There you have it. As shown above, the implementation of a service that manipulates user entities was a simple, not to say simplistic process! To demonstrate how extendable such a layer can actually be, the service in question not only can fetch, save, and delete domain objects from the persistence layer, but it can also return user objects in XML format.

Of course, I coded the ďtoXML()Ē method only for demonstration purposes; however, it should give you a clearer idea of how easy it is to encapsulate application logic behind a service, which can be consumed by several different clients layers without suffering the curse of code duplication.

At this point, the good news is you've already learned what a service is and how it can be implemented using OOP. The bad news is that, to get it up and running, itís necessary to create a slightly complex object graph.

Final Thoughts

In this fifth installment of the series, things took an exciting twist, as I finally managed to implement a fully functional user service. As you just saw, this additional layer uses the functionality of a mapper for running CRUD functions on user entities, as well as retrieving these domain objects in XML format. That's not too bad, considering that this is only an example that can be expanded and customized at will.

Naturally, if youíre anything like me, at this moment youíll want to see a script that shows how to put this service into action. Before we come to that point, though, we need to do a few more things. Construction of the entire service graph requires that we create a MySQL adapter, which is then injected into the mapperís constructor. This collaborator is finally dumped into the service itself. So we need to build a basic dependency injection container that sets this object graph and returns it to client code in a valid state.

Thatís exactly what Iíll be doing in the upcoming tutorial, so donít miss it! 



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