如何从我自己的库中访问zend 2中的getServiceLocator

I have been developing a project in zend 1 but decided to move over to zend 2 to take advantages of things like events etc.

My initial problem is that I can't seem to find any tutorials on how to use models in the way I need to use them.

What I have is an Api controller which is routed to as /api/soap

this soap endpoint loads a class that has all the methods I want to expose via SOAP

namespace MyProject\Controller;

$view = new ViewModel();
$view->setTerminal(true);
$view->setTemplate('index');

$endpoint = new EndpointController();

 $server = new Server(
            null, array('uri' => 'http://api.infinity-mcm.co.uk/api/soap')
 );


$server->setObject($endpoint);

$server->handle();

and my controller that contains all the functions is

namespace MyProject\Controller;
class EndpointController
{

    public function addSimpleProducts($products)
    {

    }

}

Now what I want to be able to do is access my products model from inside this EndpointController.

So i've tried this:

protected function getProductsTable()
{
    if (!$this->productsTable) {
        $sm = $this->getServiceLocator();
        $this->productsTable= $sm->get('MyProject\Model\ProductsTable');
    }
    return $this->productsTable;
}

When I run this I get the fatal error that EndpointController::getServiceLocator() is undefined.

I am very new to Zend 2 but in Zend 1 it feels like this would be a very minor step in my development and im getting to the point of sacking zend 2 off and going back to zend 1 or even switching to symfony 2 where its simple to use doctrine...

help?

If you want your controller to have access to the ServiceManager, then you need to inject a ServiceManager into it.

Within the MVC system, this happens pretty much automatically for you as the ServiceManager is used to create the instance of the Controller. This is not happening for you as you are creating your EndpointController using new.

You either need to create this controller via the MVC or instantiate and configure your own ServiceManager instance and pass it to EndpointController.

Alternatively, instantiate the dependencies, such as ProductTable and set them into your EndpointController.

To have access to the service locator you have to implement ServiceLocatorAwareInterface

So in any controller that will need this, you can do it like this:

namespace MyProject\Controller;

use Zend\ServiceManager\ServiceLocatorAwareInterface,
    Zend\ServiceManager\ServiceLocatorInterface;

class EndpointController implements ServiceLocatorAwareInterface
{
    protected $sm;

    public function addSimpleProducts($products) {

    }

    /**
    * Set service locator
    *
    * @param ServiceLocatorInterface $serviceLocator
    */
    public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
         $this->sm = $serviceLocator;
    }

    /**
    * Get service locator
    *
    * @return ServiceLocatorInterface
    */
    public function getServiceLocator() {
         return $this->sm;
    }
}

Now the service manager will inject itself automagically. You can then use it like:

$someService = $this->sm->getServiceLocator()->get('someService');

If you are using PHP 5.4+ you can import the ServiceLocatorAwareTrait so you don't have to define the getters and setters yourself.

class EndpointController implements ServiceLocatorAwareInterface
{
    use Zend\ServiceManager\ServiceLocatorInterface\ServiceLocatorAwareTrait