ZF2服务管理器:如何获取命名空间类实例?

时间:2014-08-08 01:16:09

标签: php zend-framework2 factory

基于我之前的问题:ZF2 Autoloader: Use factory for base class on extended classes as well

我正在尝试获取一个类的子类的实例,我在我的服务管理器配置中附加了一个抽象工厂。我知道这个工厂正在被召唤,因为我的回声正在发挥作用。我似乎遇到的问题是,我不知道如何向我的班级询问服务经理并正确使用它。

当我打这个电话时:

$x = $serviceManager->get('some\class\baseClass');

我明白了:

Error: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an 
       instance for some\class\name

当我输出传递给工厂的名称时,它会丢失斜杠,如下所示:

someclassbaseclass

班级档案

use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class baseClassFactory implements \Zend\ServiceManager\AbstractFactoryInterface
{
    public function canCreateServiceWithName (ServiceLocatorInterface $locator, $name, $requestedName = '')
    {
        return ('baseClass' === $name || is_subclass_of($name, 'baseClass'));
    }

    public function createServiceWithName (ServiceLocatorInterface $locator, $name, $requestedName = '')
    {
        $db = $locator->get('db');
        $query = new $name($db);
        return $query;
    }
}

配置

$serviceManager => array(
    'abstract_factories' => array(
        'baseClassFactory',
    ),
);

修改

在测试了这段代码之后,我已经解决了所有的错误。这是名称空间的正确工厂会计背后的代码:

namespace some\class;

use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class baseClassFactory implements \Zend\ServiceManager\AbstractFactoryInterface
{
    public function canCreateServiceWithName (ServiceLocatorInterface $locator, $name, $requestedName = '')
    {
        $baseClassName = 'some\class\baseClass';
        return ($baseClassName === $requestedName || is_subclass_of($requestedName, $baseClassName));
    }

    public function createServiceWithName (ServiceLocatorInterface $locator, $name, $requestedName = '')
    {
        // This class and sub-classes need a database connection
        $db = $locator->get('db');

        // Use the fully qualified path to the class so it inits correctly
        $createName = '\\' . $requestedName;

        // Get the system class instance
        $class = new $createName($db);

        // Pass it back to the user
        return $class;
    }
}

1 个答案:

答案 0 :(得分:1)

注册的服务名称some\class\baseClass由服务管理器在内部格式化。格式化只是小写并删除任何非字母数字字符,这将导致someclassbaseclass

创建抽象工厂时,您可以在$serviceManager->get($requestedName)方法调用中选择请求的名称服务管理器的内部名称$namesomeclassbaseclass)。

因此,唯一的变化是将$name替换为$requestedName

use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class baseClassFactory implements AbstractFactoryInterface
{
    public function canCreateServiceWithName (ServiceLocatorInterface $locator, $name, $requestedName)
    {
        return ('baseClass' === $requestedName || is_subclass_of($requestedName, 'baseClass'));
    }

    public function createServiceWithName (ServiceLocatorInterface $locator, $name, $requestedName)
    {
        $db = $locator->get('db');

        return new $requestedName($db);
    }
}