How to get the Request object from the ServiceManger in Zend Framework 2?

automatix picture automatix · Jun 18, 2013 · Viewed 11.3k times · Source

I'm developing a RESTful application and I want to build a factory that creates the proper ViewModel (Zend\View\Model\ViewModel, Zend\View\Model\JsonModel, my XmlModel) object dependent on the Accept (e.g. -H 'Accept: application/json') parameter in the HTTP request header. I want to implement this as a callback:

class Module implements ServiceProviderInterface
{

...

    public function getServiceConfig() {
        try {
            return array (
                'factories' => array(
                    'RestViewModel' => function($serviceManager) {
                        // Here I need the the Request object.
                        $requestHeadAccept = $requestObject->getHeaders()->get('Accept')->toString();
                        $return = null;
                        if (strpos($requestHeadAccept, 'application/json') != -1) {
                            $return = new JsonModel(array('data' => $data));
                        } elseif (strpos($requestHeadAccept, 'application/xml') != -1) {
                            ...
                        } else {
                            ...
                        }
                        return $return;
                    }
                )
            );
        } catch (\Exception $e) {
            ...
        }
    }

...

}

How can I get the Request object at this place?

Answer

Jurian Sluiman picture Jurian Sluiman · Jun 18, 2013

The short answer: the request is registered as Request:

$request = $serviceManager->get('Request');

However, what you aims to achieve is not a piece that belongs to the service manager's factories. It is a context dependant factory required in the controller domain. Therefore, I would create is as a controller plugin.

And to be honest, this feature is already available in ZF2 via an existing controller plugin called acceptableViewModelSelector. An example is available at the manual but this would be the scenario in your case:

use Zend\Mvc\Controller\AbstractActionController;

class SomeController extends AbstractActionController
{
   protected $acceptCriteria = array(
      'Zend\View\Model\JsonModel' => array(
         'application/json',
      ),
      'My\View\XmlModel' => array(
         'application/xml',
      ),
   );

   public function apiAction()
   {
      $model = $this->acceptableViewModelSelector($this->acceptCriteria);
   }
}

Then you will get either a JsonModel, XmlModel or by default the ViewModel.