November 6, 2012 . . Comments
Tags:


Using Traits with Zend Framework 2


Today i want to show you the usefulness of Traits within ZF 2. Some of you like me are maybe wondering when you want to have the ServiceManager injected you always have to create something like this.

<?php
namespace Application\Service;

use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;

class MyService  implements ServiceManagerAwareInterface
{
    /**
     * @var ServiceManager
     */
    protected $serviceManager;

    //implement some code here

    /**
     * Retrieve service manager instance
     *
     * @return ServiceManager
     */
    public function getServiceManager()
    {
        return $this->serviceManager;
    }

    /**
     * Set service manager instance
     *
     * @param ServiceManager $locator
     * @return User
     */
    public function setServiceManager(ServiceManager $serviceManager)
    {
        $this->serviceManager = $serviceManager;
        return $this;
    }
}

This you will probably be doing for many Services. The result... the code becomes bloated. We are not following DRY principles. Instead we are copying and pasting this code all over the place. If the structure changes sometime in the future we have to also replace this everywhere.

If you are using PHP 5.4 You are in luck as you can now use traits. I will not go into detail about traits as there are a good bunch of tutorials out there explaining these and the PHP Manual is also quite extensive on this topic.

I just want to show you a short example here on how you can actually benefit from them.

Let's get started creating a trait for ServiceManager. I assume here that you are using the ZendSkeletonApplication.
<?php
namespace Application\Provider;

use Zend\ServiceManager\ServiceManager;

trait ProvidesServiceManager
{
  /**
   * @var ServiceManager
   */
  protected $serviceManager;

  /**
   * Retrieve service manager instance
   *
   * @return ServiceManager
   */
  public function getServiceManager()
  {
      return $this->serviceManager;
  }

  /**
   * Set service manager instance
   *
   * @param ServiceManager $locator
   * @return User
   */
  public function setServiceManager(ServiceManager $serviceManager)
  {
      $this->serviceManager = $serviceManager;
      return $this;
  }
}

To use this we now go back to our Service and change it as follows:

<?php
namespace Application\Service;

use Zend\ServiceManager\ServiceManagerAwareInterface;
use Application\Provider\ProvidesServiceManager;

class MyService  implements ServiceManagerAwareInterface
{
    use ProvidesServiceManager;// Insert Trait

    // implement code here....
}

And voila, we are now using all the methods from TraitServiceManager within our own service! At the time of writing this Matthew Weier O'Phinney gave me the hint that a trait for EventManager is already existing. Thanks for that.

Let's implement that also in our Service.

<?php
namespace Application\Service;

use Zend\EventManager\EventManagerAwareInterface;
use Zend\ServiceManager\ServiceManagerAwareInterface;

use Application\Provider\ProvidesServiceManager;
use Zend\EventManager\ProvidesEvents;

class MyService  implements ServiceManagerAwareInterface, EventManagerAwareInterface
{
    use ProvidesServiceManager, ProvidesEvents; //Insert Multiple Traits

    // implement code here....
}

Now we have implement the functionality required for ServiceManager and EntityManager without needing to implement the getters/setter for these!

There are many other useful things for using Traits i can think of like DbMapper implementing a pagination etc etc etc. I hope you enjoyed this little excursion on How traits can be useful in your daily development. Happy Coding!

 

Comments

Please feel free to leave any comments as long as they're related to the topic.