【问题标题】:ZF2 ServiceManagerZF2 服务管理器
【发布时间】:2014-12-30 22:32:02
【问题描述】:

我尝试在没有 MVC 模块的情况下使用来自 zf2 的 ServiceManager。我有两个文件:classServiceManager.php 和 sm.php。

1) classServiceManager.php:

namespace ZF2;

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

class classServiceManager implements ServiceLocatorAwareInterface{
    protected $serviceLocator;

    function __construct(){
        //echo "SM: ". $this->getServiceLocator()->get('sm');
        echo "SM: ".$this->serviceLocator->get('sm');

    }

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

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

}

2) sm.php

$config = array(...);

require_once 'Zend/Loader/AutoloaderFactory.php';
Zend\Loader\AutoloaderFactory::factory($config); 
......  
use ZF2\classServiceManager;

$serviceManager = new ServiceManager();
$serviceManager->setService('sm', 'aaa');   

$a = new classServiceManager();

但是当我运行sm.php 时,我得到一个错误:

Fatal error: Call to a member function get() on a non-object....

【问题讨论】:

    标签: php zend-framework2


    【解决方案1】:

    默认情况下,Zend Framework MVC 注册一个初始化器,它将 ServiceManager 实例(Zend\ServiceManager\ServiceLocatorInterface 的实现)注入到任何实现 Zend\ServiceManager\ServiceLocatorAwareInterface 的类中。

    所以 ServiceLocatorAwareInterface 只用在 MVC 应用程序中。

    如果你想在没有 MVC 的情况下使用 zf2 的 ServiceManager,你需要自己创建一个 ServiceManager

    这是我的

    namespace Westdc\Service;
    
    use Zend\ServiceManager\ServiceManager as Zend_ServiceManager;
    
    class ServiceManager {
    
    private $serviceManager;
    
    function __construct()
    {
        $this->serviceManager = new Zend_ServiceManager;
        $this->serviceManager->addAbstractFactory(new ServiceFactory);
    
        $configService = $this->serviceManager->get('ConfigService');
        $invoked_services = $configService->get('service.invoked.ini');
    
        foreach($invoked_services as $k=>$v) {
            $this->serviceManager->setInvokableClass($k, $v);
        }
    }
    
    public function addKey($key,$value = "")
    {
        if(!empty($value))
            $this->serviceManager->$key($value);
        else
            $this->serviceManager->$key();
    }
    
    public function setServiceManager(Zend_ServiceManager $service)
    {
        $this->serviceManager = $service;
    }
    
    public function getServiceManager()
    {
        return $this->serviceManager;
    }
    
    } 
    

    这是我使用时的例子

    use Westdc\Service\ServiceManager;
    
    $serviceManager = new ServiceManager();
    $serviceManager = $serviceManager->getServiceManager();
    
    $authService = $serviceManager->get('Auth');
    

    【讨论】:

      【解决方案2】:

      现在我不太确定我的答案是否 100% 正确,但你正在做一些奇怪的事情 ;)

      1. 不要命名一个类classServiceManager这势必会在理解代码时产生冲突。
      2. 您的classServiceManager 不会神奇地注入 ZF2 的 ServiceManager。每当从 ServiceManager 调用一个类时,就会发生注入。

      所以基本上你需要做的是:

      $originalSM = new ServiceManager();
      $originalSM->setService('csm', 'ZF2\classServiceManager');
      
      $a = $orignalSM->get('csm');
      

      这样,您的 ServiceManager 将从 ZF2 的 ServiceManager 调用,然后您的 ServiceManager 将知道 ZF2,因为它会被注入。

      但是:您的 ServiceManager 将不知道__construct()。注入通过 SetterInjection 发生,因此必须先创建 Object,然后才能调用 setter。

      我的解释可能有点奇怪,但我希望你能从中有所收获。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多