处理不完整缺失字段的请求symfony形式

时间:2017-06-28 23:15:40

标签: forms symfony request

我创建了一个带有Task Entity的小型Symfony(Sf3.2 + php7)Web。我有我的控制器,我有一个新的动作来创建一个新的任务。一切都好。现在,某些表单字段不需要填充(例如,创建日期)。所以我已从我的taskType

中删除了
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add->('name')->add('description');
}

现在,我的表单完全符合我的要求。令人惊讶的是,当我提交它时,我的控制器将它传递给doctrine,并且每个丢失的字段都写为NULL。不!我不想要那个,我想要的是我的默认mysql值。

好的,我读了这份文件。似乎有两种处理数据的方法:

$form->handleRequest($request);
$form->submit($request->request->get($form->getName()));

我在API中找到了(不是在doc中)提交的第二个参数,布尔值:

API说:

bool    $clearMissing   Whether to set fields to NULL when they are missing in the submitted data.

大!这正是我所需要的。让我们看看:

public function newAction(Request $request) {
    $task = new Task();

    $form = $this->createForm('myBundle\Form\TaskType', $task);
    $form->submit($request->request->get($form->getName()), false);
    if ($form->isSubmitted() && $form->isValid()) {


        $em = $this->getDoctrine()->getManager();
        $em->persist($task);
        $em->flush();
        $response = new Response();
        $response->setContent(json_encode(array(
            'data' => 'success',
        )));
        $response->headers->set('Content-Type', 'application/json');
        return $response;

        return $this->redirectToRoute('task_success');
    }
    return $this->render('task/new.html.twig', array(
                'task' => $task,
                'form' => $form->createView(),
    ));
}

好吧,经过尝试的一切,我总是在所有缺少的字段中得到NULL。我做错了什么。

谢谢你,Caterina。

我担心必须有更多的东西。我在想,也许不是Doctrine的解决方案。 Symfony日志向我显示插入,它在每个空字段,空字段和缺少字段中设置Null。在像status这样的字段中,我可以在doctrine级别设置一个默认值,但是如果我想设置created_at字段,我想必须是Mysql,负责人正在设置当前的timeStamp。

无论如何,这是我在任务实体中的ORM属性状态。

/**
 * @var \scrumBundle\Entity\Taskstatus
 *
 * @ORM\ManyToOne(targetEntity="scrumBundle\Entity\Taskstatus")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="status", referencedColumnName="id")
 * })
 * @ORM\Column(name="status", type="integer", nullable=false,options={"default":1})
 */
private $status;

这是TaskStatus的属性ID:

/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false, options={"default":1})
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

如您所见,我尝试按照您的建议设置选项默认值。我试图创建使用handleRequest设置表单并提交相同的结果

$task = new Task();
$form = $this->createForm('scrumBundle\Form\TaskType', $task);
//$form->handleRequest($request);
$form->submit($request->request->get($form->getName()), false);
if ($form->isSubmitted() && $form->isValid()) {

我甚至尝试逐步调试提交函数,一个真正的地狱,因为提交是一个递归函数,对我来说非常复杂。

好的,再次感谢你的时间。 此致,凯特

PS。抱歉我的英语很差。; ^)

1 个答案:

答案 0 :(得分:0)

简短回答 - 当您通过Doctrine持久保存PHP对象时,您必须拥有所需的所有值集。如果您的PHP对象具有空字段,则Doctrine将在您的实体中手动将它们设置为null。 Doctrine并不认为只是因为PHP对象中的值为null,您不希望它包含在INSERT语句中。这是因为null是一个完全有效的SQL值。

因此,无论您在插入时的PHP对象是什么,都将插入到您的数据库中,null值和所有。

编辑条目时,Doctrine只会更新不同的字段,因此不需要考虑。你担心的是持久化实体。

最简单的解决方案是将MySQL默认值复制到PHP实体中。就像其中一种方式:

// set default value on the variable itself
public $someVar = 100;

// set default values in the constructor (so when creating a new entry)
public function __construct()
{
    $this->createdAt = new \DateTime();
    $this->isActive  = true;
}

您还可以在插入新条目时使用Lifecycle Callbacks进行设置:

/**
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks()
 */
class Task
{
    // ...

    /**
     * @ORM\PrePersist
     */
    public function setCreatedAtValue()
    {
        $this->createdAt = new \DateTime();
    }
}