【问题标题】:Symfony 4 forms - simple serverside validation and php type declarationsSymfony 4 forms - 简单的服务器端验证和 php 类型声明
【发布时间】:2019-03-22 10:42:53
【问题描述】:

我的表单是标准的,除了提交按钮

    {{ form_start(form) }}
    {{ form_widget(form) }}
    <input type="submit" value="{{ 'action.save'|trans }}" formnovalidate />
    {{ form_end(form) }}

我在提交按钮中使用“formnovalidate”禁用了 html5 验证, 因为,例如这里(实体用户)

/**
 * @ORM\Column(type="string")
 * @Assert\NotBlank(message="assert.notblanc")
 * @Assert\Length(
 *      min = 2,  minMessage = "assert.minmessage",
 *      max = 50, maxMessage = "assert.maxmessage"
 * )
 */
private $fullName;

只有一条简单的消息“请匹配请求的格式”(Firefox), 关于长度。不太好。

但是现在,通过“服务器端验证”,我不能像往常一样使用 PHP 类型声明。

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

public function setFullName(string $fullName): void
{
    $this->fullName = $fullName;
}

如果提交了一个空的 FullName,我得到一个 symfony 错误

“字符串”类型的预期参数,“NULL”在属性路径“fullName”中给出。

或者添加新用户时的这个

App\Entity\User::getFullName()的返回值必须是string类型,返回null

这个

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

public function setFullName(?string $fullName): void
{
    $this->fullName = $fullName;
}

解决了这个问题,但这是通常的方式,使一切都“可以为空”吗? 我也想知道......在设置值之后,断言会检查实体值吗?

-- 更新(这里是用户控制器功能)------

/**
 * @Route(
 *     path = "/user-add",
 *     name = "user_add"
 * )
 */
public function addUser(Request $request)
{
    $user = new User();

    // Update and check user
    $form = $this->createForm(UserType::class, $user);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {

        // Save it
        $this->entityManager->persist($user);
        $this->entityManager->flush();
        $this->addFlash('notice', 'Your changes were saved!');

        return $this->redirectToRoute('user_list');
    }

    return $this->render('user/user_add_update.html.twig', [
        'form' => $form->createView()
    ]);
}

/**
 * @Route(
 *     path = "/user-update/{id<[1-9]\d*>}",
 *     name = "user_update"
 * )
 */
public function updateUser(int $id, Request $request)
{
    // Get user
    $user = $this->userRepository->find($id);
    if (!$user) {
        throw $this->createNotFoundException('No user found for id ' . $id);
    }

    // Update and check user
    $form = $this->createForm(UserType::class, $user);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {

        // Save it
        $this->entityManager->persist($user);
        $this->entityManager->flush();
        $this->addFlash('notice', 'Your changes were saved!');

        return $this->redirectToRoute('user_list');
    }

    return $this->render('user/user_add_update.html.twig', [
        'form' => $form->createView(),
    ]);
}

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    正如错误所说,getFullName 必须返回一个字符串。你的getter方法是:

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

    在您声明之前:

    private $fullName;
    

    如果你把它改成:

    private $fullName = '';
    

    也就是说,分配一个默认值,getter将返回一个空字符串,不应该抛出错误。

    【讨论】:

    • 谢谢。是的,这也是“getFullName(): ?string”的替代方法
    • @ABSimon 我认为它更简洁一些,因为您不想让您的 setter 方法接受 null 并且您的 getter 方法应该严格返回 string。我主要使用 Django,问题得到了更好的解决,允许用户将 blanknull 指定为布尔值。使用 Doctrine,您可以使字段为空或不为空,但没有选项可以使字段 blankable 即不允许为空,但允许空字符串。
    【解决方案2】:

    你如何处理这个请求?

    你必须使用这个结构

    public function someControllerMethod(Request $reqest) {
      $form = $this->createForm(UserType::class);
      $form->handleRequest($request);
    
      if ($form->isSubmited && $form->isValid()){
          $user = $form->getData();
          // do some stuff
          return $this->redirect ...
      } else {
          return $this->render('editingPage.html.twig', [
            'form' => $form->createView(),
          ]);
      }
     }
    

    【讨论】:

    • 请在您的代码中添加更多解释,以便其他人可以从中学习
    • 你好,我觉得我的功能差不多;)
    • @ABSimon 而不是 $user = new User();使用我的构造,在表单验证后你可以获得新的实体 $user = $form->getData();
    • 谢谢,我明白了;)“getFullName(): ?string”仍然需要,但我可以跳过“setFullName(?string $fullName)”。类似于github.com/symfony/demo/blob/master/src/Entity/User.php
    猜你喜欢
    • 2020-01-14
    • 2016-10-16
    • 2012-09-06
    • 2013-12-26
    • 2013-10-12
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    相关资源
    最近更新 更多