Zend framework2 如何将db适配器设置为Validator NoRecordExists并在控制器中使用它?
我最近开始学习ZF2,希望有人能帮助我 我正在学习Rob Allen的Zend Framework 2教程(非常感谢@Rob Allen) 我还使用了@Allovice和@Maciej的解决方案(非常感谢这两位作者),我感到困惑,因为我没有在编辑操作中使用这个解决方案 我在Zend framework2 如何将db适配器设置为Validator NoRecordExists并在控制器中使用它?,zend-framework2,Zend Framework2,我最近开始学习ZF2,希望有人能帮助我 我正在学习Rob Allen的Zend Framework 2教程(非常感谢@Rob Allen) 我还使用了@Allovice和@Maciej的解决方案(非常感谢这两位作者),我感到困惑,因为我没有在编辑操作中使用这个解决方案 我在'adapter'=>$this->getServiceLocator()->get('Zend\Db\adapter\adapter')中看到了致命错误:对非对象调用成员函数get() 1) 在Module.php中添加了
'adapter'=>$this->getServiceLocator()->get('Zend\Db\adapter\adapter')中看到了致命错误:对非对象调用成员函数get()
1) 在Module.php中添加了
及
3) 在addAction中的RegionController.php中,使用
$model=$this->getServiceLocator()->get('RegionModel')
而不是$model=newregion()代码>
这对addAction很好,但我不明白如何在editAction中使用它
我的
My RegionTable具有以下代码:
非常感谢所有回答我问题的人
向您致意,Ruslan。您应该通过服务管理器实例化一个新实体,以使用数据库适配器,而不是使用从表中收集的实体的表单过滤器
您有几个选择:
将输入过滤器移动到它自己的类中,并通过服务管理器进行实例化,以便注入数据库适配器
将表网关工厂中的原型对象更改为通过service manager工厂实例化
通过服务管理器实例化一个单独的实体,并从中获取输入过滤器
我个人会选择选项1,因为它能更好地分离代码
一些例子:
选项1(我的选择):
这涉及到将过滤器移动到它自己的文件和类,在注入数据库适配器的同时为它创建一个工厂。然后,我们将在控制器中通过服务管理器获取过滤器,并将过滤器应用于表单
因此,首先将过滤器移动到ModName\src\ModName\Form\RegionFilter.php中的一个文件中,用模块名替换ModName
并将代码更改为如下所示:
然后,您将在Module.php中创建类似的工厂:
公共函数getServiceConfig()
{
返回数组(
“工厂”=>数组(
'ModName\Form\RegionFilter'=>函数($sm){
$dbAdapter=$sm->get('Zend\Db\Adapter\Adapter');
返回新的RegionFilter($dbAdapter);
},
),
);
}
最后,在控制器中,只需执行以下操作:
if($request->isPost()){
$filter=$this->getServiceLocator()->get('ModName\Form\RegionFilter');
$form->setInputFilter($filter->getInputFilter());
$form->setData($request->getPost());
如果($form->isValid()){
$this->getRegionTable()->save($form->getData());
返回$this->redirect()->toRoute('zfcadmin/regions');
}
}
选项2:
这涉及到使用Region
injected的实例构造表。然后您可以将原型设置为此
因此,在您的表构造中:
public function\u构造(适配器$Adapter,区域$Region)
{
$this->adapter=$adapter;
$this->resultSetPrototype=newresultset();
$this->resultSetPrototype->setArrayObject原型($region);
$this->initialize();
}
然后你的工厂:
公共函数getServiceConfig()
{
返回数组(
'invokables'=>数组(
'RegionModel'=>'FcLibraries\Model\Region',
),
“工厂”=>数组(
'FcLibraries\Model\RegionTable'=>函数($sm){
$region=$sm->get('RegionModel');
$dbAdapter=$sm->get('Zend\Db\Adapter\Adapter');
$table=新RegionTable($dbAdapter,$region);
返回$table;
},
),
);
}
您应该能够保持代码的其余部分不变。如控制器。现在我还没有测试过这个方法,所以我不是百分之百的认为它会工作,但我认为它应该。另外两种方法我以前也用过
选项3(最简单):
这涉及通过服务管理器获取一个单独的区域模型,并使用该模型将输入过滤器应用于表单
公共函数editAction()
{
$id=(int)$this->params()->fromRoute('id',0);
如果(!$id){
返回$this->redirect()->toRoute('zfcadmin/region',数组(
“操作”=>“添加”
));
}
$data=$this->getRegionTable()->get($id);
$form=newregionform();
$form->bind($data);
$form->get('submitBtn')->setAttribute('value','Save');
$request=$this->getRequest();
如果($request->isPost()){
$region=$this->getServiceLocator()->get('RegionModel');
$form->setInputFilter($region->getInputFilter());
$form->setData($request->getPost());
如果($form->isValid()){
$this->getRegionTable()->save($form->getData());
返回$this->redirect()->toRoute('zfcadmin/regions');
}
}
返回数组(
'id'=>$id,
'form'=>$form,
);
}
我还没有测试代码,但你应该了解要点。任何问题都可以提问。不要使用从表中收集的实体的表单过滤器,而应该通过服务管理器实例化一个新实体以使用数据库适配器 您有几个选择:
public function getServiceConfig()
{
return array(
'invokables' => array(
'RegionModel' => 'FcLibraries\Model\Region', //<-- added it
),
'factories' => array(
'FcLibraries\Model\RegionTable' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new RegionTable($dbAdapter);
return $table;
},
),
);
}
/**
* @var
*/
protected $serviceLocator;
/**
* @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator
* @return Library
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
return $this;
}
/**
* @return \Zend\ServiceManager\ServiceLocatorInterface
*/
public function getServiceLocator()
{
return $this->serviceLocator;
}
$inputFilter->add($factory->createInput(array(
'name' => 'name',
'required' => true,
'filters' => $this->_filters,
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 30,
),
),
array(
'name' => 'Db\NoRecordExists',
'options' => array(
'table' => $this->table,
'field' => 'name',
//'exclude' => array(
// 'field' => 'id',
// 'value' => $this->id
//),
'adapter' => $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'),
),
),
),
)));
public function editAction()
{
$id = (int)$this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('zfcadmin/region', array(
'action' => 'add'
));
}
$data = $this->getRegionTable()->get($id);
$form = new RegionForm();
$form->bind($data);
$form->get('submitBtn')->setAttribute('value', 'Save');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($data->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getRegionTable()->save($form->getData());
return $this->redirect()->toRoute('zfcadmin/regions');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
/**
* @param \Zend\Db\Adapter\Adapter $adapter
*/
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
$this->resultSetPrototype = new ResultSet();
$this->resultSetPrototype->setArrayObjectPrototype(new Region());
$this->initialize();
}
public function get($id)
{
$id = (int)$id;
$rowSet = $this->select(array('id' => $id));
$row = $rowSet->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=zf2tutorial;host=localhost',
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter' => function ($serviceManager) {
$adapterFactory = new Zend\Db\Adapter\AdapterServiceFactory();
$adapter = $adapterFactory->createService($serviceManager);
\Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter);
return $adapter;
}
),
)
array(
'table' => 'users',
'field' => 'username',
'adapter' => \Zend\Db\TableGateway\Feature\GlobalAdapterFeature::getStaticAdapter();
)