【问题标题】:ZF2 Service Manager: How to get a namespace class instance?ZF2 服务管理器:如何获取命名空间类实例?
【发布时间】:2014-08-08 01:16:09
【问题描述】:

基于我之前的问题: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;
    }
}

【问题讨论】:

  • 改用$requestedName 参数,这是您请求的服务的实际名称。
  • @Crisp 是正确的,但为了详细说明,ServiceManager 将小写并格式化您注册的所有服务别名。所以some\class\baseClass(即$requestedName)内部被键入为someclassbaseclass$name)。
  • @AlexP 你能提交这个作为答案吗?

标签: php zend-framework2 factory


【解决方案1】:

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

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

所以唯一的改变就是将 $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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多