ZF2服务管理器使用自定义类

时间:2014-02-11 14:16:00

标签: zend-framework2

看起来它已经被触摸了好几次,但我仍然无法让它发挥作用。我在一个单独的模块中设置了一个JSON-RPC服务器,它工作正常。它的功能在于一个新的类Rpcapi。现在我想重用已经在该类的另一个模块中实现的DB相关函数。根据ZF2文档,我的Rpcapi类必须是ServiceLocator感知的,看起来我就是这样做的。不幸的是仍然无法让它发挥作用。请帮助记住,我是ZF2的新手:)

Rpccontroller.php

 namespace Rpc\Controller;

 use Zend\Mvc\Controller\AbstractActionController;
 use Zend\Json\Server\Server;
 use Zend\Json\Server\Smd;
 use Rpc\Model\Rpcapi;

class RpcController extends AbstractActionController
{   
    public function indexAction()
    {
        header('Content-Type: application/json');
        $jsonrpc = new Server();
        $jsonrpc->setClass(new Rpcapi);
        $jsonrpc->getRequest()->setVersion(Server::VERSION_2);
        if ($this->getRequest()->getMethod() == "GET") {
            $smd = $jsonrpc->getServiceMap()->setEnvelope(Smd::ENV_JSONRPC_2);
            echo $smd;
        } else {
            $jsonrpc->handle();         
        }
    }
}

用于Rpc模块的module.config.php

'service_manager' => array(
    'invokables' => array(
        'rpcapi' => 'Search\Model\SiteTable',
    ),
),

Rpcapi.php         名称空间Rpc \ Model;

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

class Rpcapi implements ServiceLocatorAwareInterface 
{

   protected $services;
   protected $siteTable;

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->services = $serviceLocator;
    }

    public function getServiceLocator()
    {
        return $this->services;
    }

    public function getSiteTable()
    {
     if (!$this->siteTable) {
        $sm = $this->getServiceLocator();
        $this->siteTable = $sm->get('rpcapi');
     }
     return $this->siteTable;
    }
        /**
        * Returns list of all sites
        * 
        *
        * @return array
        */
        public function getAllSites()
        {
        $results = $this->getSiteTable()->fetchAll();
        $r = array ('1' => '1', '2' => 2); //Just to return something for now
        return $r;
         }
}

所有我能解决的是:致命错误:在/var/www/html/AmeriFluxZF2/module/Rpc/src/Rpc/Model/Rpcapi.php上的非对象上调用成员函数get()第28行。第28行是:       $ this-> siteTable = $ sm-> get('rpcapi');

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

让类服务定位器知道告诉ZF2应该在实例化时将服务定位器注入到您的类中。但是,您仍然需要使用服务定位器来实例化此类,而不是自己创建它的实例,否则这种情况永远不会发生。

您可能希望为Rpcapi类的invokable添加新条目,然后从服务定位器中获取此条目,而不是在控制器中执行new Rpcapi

PS:你的类的命名非常混乱 - 你有一个Rpcapi类和一个名为rpcapi的invokable,但这个invokable创建了一个完全不同的类的实例?

答案 1 :(得分:2)

如果您希望Rpcapi中的服务经理注入serviceLocator,您必须通过服务管理器本身获取它:

'service_manager' => array(
    'invokables' => array(
        'rpcapi' => 'Search\Model\SiteTable',
        'Rpc\Model\Rpcapi' => 'Rpc\Model\Rpcapi',
    ),
),

行动:

public function indexAction()
    {
        header('Content-Type: application/json');
        $jsonrpc = new Server();
        $jsonrpc->setClass($this->getServiceLocator()->get('Rpc\Model\Rpcapi'));
        $jsonrpc->getRequest()->setVersion(Server::VERSION_2);
        if ($this->getRequest()->getMethod() == "GET") {
            $smd = $jsonrpc->getServiceMap()->setEnvelope(Smd::ENV_JSONRPC_2);
            echo $smd;
        } else {
            $jsonrpc->handle();         
        }
    }

在这里您可以看到SiteTable的'rcpai'名称不是一个好选择...;)