Doctrine Zend Form 未在 post 上设置数据

Doctrine Zend Form not setting data on post

我对 Zend 和 Doctrine 很陌生

正在使用 ORM 创建 Zend 模块,但我 post 时未设置数据。

我检查了 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 文件,并获得了所有 getters/setters 方法以及 ORM 设置。 运行 schema:update 也有效并将新的 table 添加到数据库。

我的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>

问题

当我提交表单时,它不会更新 table,因为所有 post 数据都是空的。我还测试了通过执行 var_dump($request->getPost()) 来检查它是否 posting,并且它 returns 所有传递的数据。但是,当我在 $form->isValid() 之后检查 var_dump($form->getData()); 时,它 returns 所有 NULL 数据。

检查了一整天并尽我所能,但没有任何运气。请帮忙。

我猜 Form 文件有问题,但不确定。

尝试更改这两行

$form->setData($request->getPost());
if ($form->isValid()) {

//$form->setData($request->getPost());
if ($form->isValid($request->getPost())) {

好的,经过几天缩小问题范围,终于找到了解决方案。

基本上我在 Entity class 中有错误的语法。我用 "_" 声明我的变量,这是导致问题的原因,因为它不是用我的 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 如何协同工作。

我希望这会在不久的将来对某人有所帮助。