据我所知,这不是直接可能的,但我在某处读到初始化器适用于这种类型的场景。
initializer 可以是任何实现 InitializerInterface 的类,它有一个方法 initialize(),initialize() 方法是用对象(模型的实例)和服务管理器实例调用的,你需要为每个对象编写条件需要初始化。构建初始化器类后,您需要在服务管理器配置(module.config.php)或 getServiceConfig() 方法中包含条目
虽然没有完全涵盖您的问题,但可能有助于朝着正确的方向前进
编辑
实现这一目标的最佳做法是什么?
回答这个问题
如果您的对象没有依赖项,您可以将其实现为
$myObject = new Model();
$myObject->find($id); which would initialize the model
如果您的模型具有依赖关系,并且如果您需要在开发阶段的后期将模型替换为其他对象,您可以将对象创建过程与服务定位器的服务工厂配置隔离开来,以实现这一点,在 getServicConfig() 方法中定义服务Module.php(您也可以定义自己的工厂代码并在配置中引用它,但在大多数用例中,简单的工厂定义就足够了)
public function getServiceConfig(){
return array(
'factories' => array(
'Model' => function(ServiceLocatorInterface $sm) {
return new Model($dependency1, $dependency2...);
},
),
);
}
然后模型访问代码将是
$myObject = $this->serviceLocator()->get('Model');
$myObject->find($id); which would initialize the model
最佳实践是定义一个接口,其中包括 find($id) 和所有其他需要调用的方法并在 Model 类中实现此接口,这样您就可以用实现该接口的任何其他对象替换您的工厂代码和您无需触摸 Model 对象的使用代码。
对于用例二,我假设您尝试重用或减少代码重复。如果你有一组有限的组合,你可以像下面这样实现
像这样定义服务工厂
public function getServiceConfig(){
return array(
'factories' => array(
'Model/table1' => function(ServiceLocatorInterface $sm) {
return new TableGateway('table1', $sm->get('db'));
},
'Model/table2' => function(ServiceLocatorInterface $sm) {
return new TableGateway('table2', $sm->get('db'));
},
.
.
.
.
),
);
}
访问 table1 作为
$tableGateway = $this->serviceLocator()->get('Model/table1');
注意:'Model/table1'是命名空间,避免覆盖配置,内部'/'将被服务管理器删除,名称将小写,注册和获取。
Zend\ServiceManager\ServiceManager 将它调用的内容存储canonicalNames
在一个受保护的属性中。这是一个映射到规范名称的命名空间数组,这些命名空间是带有斜线并变为小写的命名空间。