基于我之前的问题: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;
}
}
答案 0 :(得分:1)
注册的服务名称some\class\baseClass
由服务管理器在内部格式化。格式化只是小写并删除任何非字母数字字符,这将导致someclassbaseclass
。
创建抽象工厂时,您可以在$serviceManager->get($requestedName)
方法调用中选择请求的名称,也服务管理器的内部名称$name
(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);
}
}