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-&gt;getPost()) 测试了它是否正在发布,它会返回所有传递的数据。但是,当我在 $form-&gt;isValid() 之后检查 var_dump($form-&gt;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+Doctrine yml 模式问题

Zend+Doctrine2:如何使用 ArrayCollections() 正确刷新实体?

Zend2 框架 - 给映射异常的 Doctrine ORM

PHP 将Zend Framework 1.10与Doctrine 2集成(使用Doctrine的Autoloader)

Zend Framework 2 + Doctrine 2 [关闭]

如何将嵌入的 Doctrine 文档填充到 Zend 字段集中?