【问题标题】:Symfony form submission with handleRequest issue带有 handleRequest 问题的 Symfony 表单提交
【发布时间】:2018-04-23 10:05:02
【问题描述】:

我在Symfony 4 中的表单验证时遇到了一个奇怪的错误。这是一个由该实体表示的简单联系表单。

class ContactRequest
{
    /** @var int */
    private $id;

    /** @var string */
    private $fullName;

     //...

    /**
     * @return string
     */
    public function getFullName() : string
    {
        return $this->fullName;
    }

在我的控制器中,我正在根据 Symfony 网站处理提交,但我缺少一些东西,因为我收到以下错误:

Type error: Return value of App\Entity\ContactRequest::getFullName() must be of the type string, null returned

现在,我知道这是什么意思了:它期望方法 getFullName 返回一个字符串,而实际上返回的是 null,但我不明白为什么。

这是我的控制器

   public function contactSubmit(Request $request, ValidatorInterface $validator)
   {

        $form = $this->createForm(ContactType::class);

        $form->handleRequest($request);

        if($form->isValid()){
          //...
        }

        $errors = $validator->validate($form);

现在我的问题是。 handleRequest 方法不应该为我设置实体中的值吗? 令我惊讶的是,当我之前初始化实体时,它运行良好,尽管实体已经在configureOptions 方法中以如下形式设置:

$contact = new ContactRequest;
$contact
    ->setFullName($request->request->get('contact')['fullName'])
    //...

    $form = $this->createForm(
        ContactType::class
        $contact
    );
    $form->setData($contact);

    $form->handleRequest($request);

但是,使用handleRequest 的范围不应该是避免手动设置实体的值吗? handleRequest 方法不应该负责设置这些值吗? 我知道我也可以针对实体验证提交的数据(我已经成功尝试过),根本不使用handleRequest,但这会让我有点生气。为什么在这种情况下需要设置表单?

这是我的表单 (ContactType)

 //...
 public function buildForm(FormBuilderInterface $builder, array $options)
 {
        $builder
            ->add('fullName', TextType::class, [
                'required' => true,
                'empty_data' => 'a',
                'attr' => [
                    'placeholder' => 'Full Name',
                    'class' => 'form-control'
                ]
            ])
        //...
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => ContactRequest::class
    ]);
}

请赐教:)

【问题讨论】:

  • 您缺少createForm 的第二个参数(对ContactRequest 实例的引用)。 handleRequest应该怎么知道在哪里设置数据?
  • ContactRequest 引用已经以configureOptions 方法的形式设置。但是,即使我像你所说的那样通过它$form = $this->createForm(ContactType::class, new ContactRequest); ,问题仍然存在,除非我使用设置器手动设置实体中的数据
  • 先尝试将其设置为变量,例如:$contactRequest = new ContactRequest(); $form = $this->createForm(ContactType::class, $contactRequest);。如果您发布完整的控制器也可能会有所帮助 - 以防万一......做new -> createForm -> handleRequest -> isValid肯定就足够了。
  • 我已经尝试了所有这些。没有任何变化
  • 我猜逻辑解决方案是然后删除类型提示(因为您基本上是在该字段中使用空值初始化实体)。 PHP 仅支持 v7.1 的可空类型提示(?string 将是那里的语法)

标签: symfony symfony-forms symfony4 symfony-validator


【解决方案1】:

为了找出您的 getFullName 被调用的位置,您可以(至少在开发环境中)打印调用的回溯:

/**
 * @return string
 */
public function getFullName() : string
{
    if ($this->fullName === null)
    {
        echo "<pre>getFullName on uninitialized entity:\n";
        debug_print_backtrace();
        die();
    }
    return $this->fullName;
}

但正如 cmets 中所说:在该字段中使用空值初始化实体并且不允许 getter 返回空值对我来说似乎有点奇怪,所以: ?string 允许可空返回值(从 PHP 7.1) 似乎是下一个最佳选择。

【讨论】:

    猜你喜欢
    • 2014-02-03
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 2014-05-10
    • 2010-10-09
    • 1970-01-01
    相关资源
    最近更新 更多