Doctrine Zend Form 未在帖子中设置数据
Posted
技术标签:
【中文标题】Doctrine Zend Form 未在帖子中设置数据【英文标题】:Doctrine Zend Form not setting data on post 【发布时间】:2015-08-29 07:16:58 【问题描述】:我对 Zend 和 Doctrine 很陌生
使用 ORM 为 Zend 创建一个模块,但是当我发布时,没有设置数据。
我检查了this,但没有运气。
我的module.config.php
<?php
return array(
'controllers' => array(
'invokables' => array(
'Room\Controller\Index' => 'Room\Controller\IndexController',
),
),
'router' => array(
//other stuff
//
),
'may_terminate' => true,
),
),
),
'view_manager' => array(
'display_exceptions' => true,
'template_path_stack' => array(
'room' => __DIR__ . '/../view'
),
),
'service_manager' => array (
'factories' => array(
'room_module_options' => 'Room\Service\Factory\ModuleOptionsFactory',
'room_error_view' => 'Room\Service\Factory\ErrorViewFactory',
'room_form' => 'Room\Service\Factory\RoomFormFactory',
),
),
'doctrine' => array(
'configuration' => array(
'orm_default' => array(
'generate_proxies' => true,
),
),
'driver' => array(
'room_driver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(
__DIR__ . '/../src/Room/Entity',
),
),
'orm_default' => array(
'drivers' => array(
'Room\Entity' => 'room_driver',
),
),
),
),
);
我在Entity
文件夹中有我的Room.php
文件,并且拥有所有getter/setters 方法以及ORM 设置。运行schema:update
也可以工作并将新表添加到数据库中。
我的Factory/RoomFormFactory.php
<?php
namespace Room\Service\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use DoctrineORMModule\Form\Annotation\AnnotationBuilder as DoctrineAnnotationBuilder;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use DoctrineModule\Validator\NoObjectExists as NoObjectExistsValidator;
use Room\Entity\Room;
class RoomFormFactory implements FactoryInterface
/**
* @var Zend\Form\Form
*/
private $form;
/**
* @var ServiceLocatorInterface
*/
private $serviceLocator;
/**
* @var ModuleOptions
*/
protected $options;
/**
* @var Doctrine\ORM\EntityManager
*/
protected $entityManager;
/**
* @var Zend\Mvc\I18n\Translator
*/
protected $translatorHelper;
/**
* @var Zend\Mvc\I18n\Translator
*/
protected $url;
public function createService(ServiceLocatorInterface $serviceLocator)
$this->serviceLocator = $serviceLocator;
return $this;
/**
* Add Room
*
* Method to create the Doctrine ORM room form for edit/add room
*
* @return Zend\Form\Form
*/
public function createRoomForm($roomEntity, $formName = 'AddRoom')
$entityManager = $this->getEntityManager();
$builder = new DoctrineAnnotationBuilder($entityManager);
$this->form = $builder->createForm($roomEntity);
$this->form->setHydrator(new DoctrineHydrator($entityManager));
$this->form->setAttribute('method', 'post');
$this->addCommonFields();
switch($formName)
case 'AddRoom':
//$this->addRoomFields();
//$this->addRoomFilters();
$this->form->setAttributes(array(
'action' => $this->getUrlPlugin()->fromRoute('room', array('action' => 'add')),
'name' => 'add_room'
));
break;
case 'EditRoom':
$this->form->setAttributes(array(
'name' => 'add_room'
));
break;
default:
//$this->addRoomFields();
//$this->addRoomFilters();
$this->form->setAttributes(array(
'action' => $this->getUrlPlugin()->fromRoute('room', array('action' => 'add')),
'name' => 'add_room'
));
break;
$this->form->bind($roomEntity);
return $this->form;
/**
*
* Common Fields
*
*/
private function addCommonFields()
$this->form->add(array(
'name' => 'csrf',
'type' => 'Zend\Form\Element\Csrf',
'options' => array(
'csrf_options' => array(
'timeout' => 600
)
)
));
$this->form->add(array(
'name' => 'submit',
'type' => 'Zend\Form\Element\Submit',
'attributes' => array(
'type' => 'submit',
),
));
/**
* get options
*
* @return ModuleOptions
*/
private function getOptions()
if(null === $this->options)
$this->options = $this->serviceLocator->get('room_module_options');
return $this->options;
/**
* get entityManager
*
* @return Doctrine\ORM\EntityManager
*/
private function getEntityManager()
if(null === $this->entityManager)
$this->entityManager = $this->serviceLocator->get('doctrine.entitymanager.orm_default');
return $this->entityManager;
/**
* get translatorHelper
*
* @return Zend\Mvc\I18n\Translator
*/
private function getTranslatorHelper()
if(null === $this->translatorHelper)
$this->translatorHelper = $this->serviceLocator->get('MvcTranslator');
return $this->translatorHelper;
/**
* get urlPlugin
*
* @return Zend\Mvc\Controller\Plugin\Url
*/
private function getUrlPlugin()
if(null === $this->url)
$this->url = $this->serviceLocator->get('ControllerPluginManager')->get('url');
return $this->url;
我的Controller/IndexController.php
<?php
namespace Room\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Room\Entity\Room;
use Room\Options\ModuleOptions;
use Room\Service\RoomService as RoomCredentialsService;
/**
* Index controller
*/
class IndexController extends AbstractActionController
/**
* @var ModuleOptions
*/
protected $options;
/**
* @var Doctrine\ORM\EntityManager
*/
protected $entityManager;
/**
* @var Zend\Mvc\I18n\Translator
*/
protected $translatorHelper;
/**
* @var Zend\Form\Form
*/
protected $roomFormHelper;
/**
* Index action
*
* Method to show an Rooms
*
* @return Zend\View\Model\ViewModel
*/
public function indexAction()
$rooms = $this->getEntityManager()->getRepository('Room\Entity\Room')->findall();
return new ViewModel(array('rooms' => $rooms));
/**
* Add room
*
* Method to add room
*
* @return Zend\View\Model\ViewModel
*/
public function addAction()
try
$room = new Room;
$identity = $this->identity();
$form = $this->getRoomFormHelper()->createRoomForm($room, 'AddRoom');
$request = $this->getRequest();
if ($request->isPost())
$form->setValidationGroup('room_code', 'room_number', 'program_time', 'room_size', 'csrf');
$form->setData($request->getPost());
if ($form->isValid())
$entityManager = $this->getEntityManager();
$room->setCreatedDate(new \DateTime());
//var_dump($form->getData()); die(); //gives all NULL value; prob setData() not working
$entityManager->persist($room);
$entityManager->flush();
$this->flashMessenger()->addSuccessMessage($this->getTranslatorHelper()->translate('Room Added Successfully'));
return $this->redirect()->toRoute('room');
catch (\Exception $e)
return $this->getServiceLocator()->get('room_error_view')->createErrorView(
$this->getTranslatorHelper()->translate('Something went wrong during adding room! Please, try again later.'),
$e,
$this->getOptions()->getDisplayExceptions(),
false
);
$viewModel = new ViewModel(array('form' => $form));
$viewModel->setTemplate('room/index/add');
return $viewModel;
/**
* get options
*
* @return ModuleOptions
*/
private function getOptions()
if (null === $this->options)
$this->options = $this->getServiceLocator()->get('room_module_options');
return $this->options;
/**
* get entityManager
*
* @return EntityManager
*/
private function getEntityManager()
if (null === $this->entityManager)
$this->entityManager = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
return $this->entityManager;
/**
* get translatorHelper
*
* @return Zend\Mvc\I18n\Translator
*/
private function getTranslatorHelper()
if (null === $this->translatorHelper)
$this->translatorHelper = $this->getServiceLocator()->get('MvcTranslator');
return $this->translatorHelper;
/**
* get roomFormHelper
*
* @return Zend\Form\Form
*/
private function getRoomFormHelper()
if (null === $this->roomFormHelper)
$this->roomFormHelper = $this->getServiceLocator()->get('room_form');
return $this->roomFormHelper;
现在是我的add.phtml
<?php
$form = $this->form;
/**
*
* Set form fields classes and placeholders here
*
*/
$form->setAttributes(array(
'class' => 'form'
));
$form->get('room_code')->setAttributes(array(
'required' => 'true',
'class' => 'form-control input-lg',
'placeholder' => $this->translate('Room Code')
));
$form->get('room_number')->setAttributes(array(
'required' => 'false',
'class' => 'form-control input-lg',
'placeholder' => $this->translate('Room Number')
));
$form->get('program_time')->setAttributes(array(
'required' => 'false',
'class' => 'form-control input-lg',
'placeholder' => $this->translate('Program Time')
));
$form->get('room_size')->setAttributes(array(
'required' => 'true',
'class' => 'form-control input-lg',
'placeholder' => $this->translate('Room Size')
));
$form->get('submit')->setAttributes(array(
'class' => 'btn btn btn-success btn-lg',
'value' => $this->translate('Add Room')
));
$form->prepare();
?>
<div class="">
<h2><?php echo $this->translate('Add Room')?></h2>
<div class="containe" id="wrap">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<?php echo $this->form()->openTag($form); ?>
<?php
$element = $form->get('room_code');
echo $this->formElement($element);
echo $this->formElementErrors($element);
?>
</div>
<div class="form-group row">
<div class="col-xs-4 col-md-4">
<?php
$element = $form->get('room_number');
echo $this->formElement($element);
echo $this->formElementErrors($element);
?>
</div>
<div class="col-xs-4 col-md-4">
<?php
$element = $form->get('program_time');
echo $this->formElement($element);
echo $this->formElementErrors($element);
?>
</div>
<div class="col-xs-4 col-md-4">
<?php
$element = $form->get('room_size');
echo $this->formElement($element);
echo $this->formElementErrors($element);
?>
</div>
</div>
<div class="form-group row">
<div class="col-sm-12">
<?php echo $this->formRow($form->get('submit'))?>
</div>
</div>
<?php
echo $this->formRow($form->get('csrf'));
echo $this->form()->closeTag();
?>
</div>
</div>
</div>
</div>
问题
当我提交表单时,它不会更新表格,因为所有帖子数据都是空的。我还通过var_dump($request->getPost())
测试了它是否正在发布,它会返回所有传递的数据。但是,当我在 $form->isValid()
之后检查 var_dump($form->getData());
时,它会返回所有 NULL 数据。
检查了一整天,尽我所能,但没有任何运气。请帮忙。
我猜Form
文件有问题,但不确定。
【问题讨论】:
【参考方案1】:好吧,终于经过几天缩小问题找到了解决方案。
基本上我在 Entity 类中有错误的语法。我用"_"
声明了我的变量,这导致了问题,因为我的getter 和setter 没有调用它。
例如,我有像 $room_code
这样的变量,我的这个变量的 getter/setter 是:
public function setRoomCode($room_code)
$this->room_code = $room_code;
return $this;
public function getRoomCode()
return $this->room_code;
Zend 的正确做法
$roomCode; //declaring variable.
//setter
public function setRoomCode($roomCode)
$this->roomCode = $roomCode;
return $this;
//getter
public function getRoomCode()
return $this->roomCode;
真的很可怜我,但我想它给了我很好的时间来学习 zend 和 orm 如何协同工作。
我希望这将在不久的将来帮助某人。
【讨论】:
【参考方案2】:尝试改变这两行
$form->setData($request->getPost());
if ($form->isValid())
到
//$form->setData($request->getPost());
if ($form->isValid($request->getPost()))
【讨论】:
有了这个,它根本不发送数据。它不断询问字段是必需的。以上是关于Doctrine Zend Form 未在帖子中设置数据的主要内容,如果未能解决你的问题,请参考以下文章
Zend+Doctrine2:如何使用 ArrayCollections() 正确刷新实体?
Zend2 框架 - 给映射异常的 Doctrine ORM
PHP 将Zend Framework 1.10与Doctrine 2集成(使用Doctrine的Autoloader)