我是Zend 2的新手并且有这种情况。想知道处理这种情况的最佳方法。
在Application模块中我有这些类
namespace Application\Foo;
class Base {
protected $this->services; //service locator
public function myFunc() {
//needs service locator here
$this->services;
}
}
namespace Application\Foo;
class A extends Base {
//can have some method that uses $this->services;
}
namespace Application\Foo;
class B extends Base {
}
正如您所看到的,我需要Base类中的服务定位器。然后我想在我的控制器中使用A,B ......扩展类。
感谢您的建议
更新
根据jmleroux的建议,我更新了代码,看起来像这样
namespace Application\Foo;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class Base implements ServiceLocatorAwareInterface {
protected $this->services; //service locator
public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
$this->services = $serviceLocator;
}
public function getServiceLocator() {
return $this->services;
}
public function myFunc() {
//needs service locator here
$this->services;
}
}
module.conf.php
service_manager => array(
'invokables' => array(
'my_ser' => 'Application\Foo\Base'
)
)
在我的控制器中
$this->serviceLocator->get('my_ser');
返回加载了服务定位器的基类
现在我的问题是如何在加载服务定位器的情况下获取扩展类(A,B ...)。从那以后
$x = new \Application\Foo\A();
没有加载服务定位器。我是否必须将所有扩展类添加到模块配置中作为 invokables ?还是有更好的选择。
再次感谢。
更新2
感谢所有人(特别是@jmleroux)的支持。找到这些解决方案,我在这里添加它们认为它将帮助其他人
注意:只是一个大致的想法。名称空间和类名称不准确
解决方案1(推荐) - 使用ServiceLocatorAwareInterface / ServiceLocatorAwareTrait for php 5.4 +
每个类实现ServiceLocatorAwareInterface并将其添加到服务管理器
namespace Application\Foor;
class A implements ServiceLocatorAwareInterface {
protected $services;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator) {
$this->services = $serviceLocator;
}
public function getServiceLocator() {
return $this->services;
}
}
class B implements ServiceLocatorAwareInterface {
use ServiceLocatorAwareTrait;
}
module.conf.php(或在模块getServiceConfig()函数内部)
'service_manager' => array(
'invokables' => array(
'my_ser_a' => 'Application\Foo\A',
'my_ser_b' => 'Application\Foo\B',
......
)
)
在控制器内按名称调用服务
解决方案2 - 使用AbstractFactoryInterface
创建工厂类
class MyFac implements AbstractFactoryInterface {
public function canCreateServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName) {
if (class_exists($requestedName)){ \\eg. check Application\Foo\A exists
return true;
}
return false;
}
public function createServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName) {
$class = new $requestedName; \\eg. creates an instance of Application\Foo\A
$class->setServiceLocator($locator); \\make sure your class has this method
return new $class;
}
}
module.conf.php(或在模块getServiceConfig()函数内部)
'service_manager' => array(
'abstract_factories' => array(
'Application\Foo\MyFac'
)
)
在控制器中调用
$this->getServiceLocator()->get('Application\Foo\A');
感谢。
答案 0 :(得分:2)
为了访问服务定位器,您的基类需要声明为实现ServiceLocatorAwareInterface.php的可调用服务
如果您使用的是PHP 5.4+,则可以使用ServiceLocatorAwareTrait.php