【问题标题】:Argument 1 passed to App\Entity\User::setToken() must be an instance of App\Entity\Token or null, string given, called in传递给 App\Entity\User::setToken() 的参数 1 必须是 App\Entity\Token 或 null 的实例,给定字符串,调用
【发布时间】:2019-04-10 16:32:03
【问题描述】:

我正在尝试更新我的数据库中的一行。

在这种情况下,我使用两个实体 UserToken

这是我在控制器中的方法:

/**
 * @Route("/forget-password/", name="forget", methods="GET|POST")
 */
 public function emailrestore(Request $request, UserRepository $userrepository, TokenGenerator $tokengenerator, MailGenerator $mailgenerator)
 {
    $userInfo = ['email' => null];
    $form = $this->createForm(ForgetPasswordType::class, $userInfo);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $userInfo = $form->getData();
        $email = $userInfo['email'];
        $user = $userrepository->findOneBy(['email' => $email]);
        if ($user === null){
            $message = "This email doesn't exist in our database or is wrong.";
            $this->session->getFlashBag()->add("danger", $message);
            return $this->redirectToRoute('forget');
        }
        // 2.5) Generating token
        $pledge = $tokengenerator->generateToken();
        $url = $this->generateUrl('recovery/', 
        array(
            'token' => $pledge
        ),
        UrlGeneratorInterface::ABSOLUTE_URL
        );
        $user->setToken($pledge);
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($token);
        $entityManager->flush();
        // 6) Sending the email to the user
        //$mailgenerator->registration($email, $url);
    }         
    return $this->render('emails/forget-password/forget-password.html.twig', array (
        'form' => $form->createView(),
    ));
 }

正如你在 dump($user); 部分看到的那样我通过我的请求获得了以下数据:

据我在同一部分了解,在转储($user)附近。我想使用 $token->setToken($pledge)

方法更新我的用户的新令牌

管理这个问题的正确方法是什么?

感谢您的宝贵时间。

【问题讨论】:

    标签: php symfony doctrine


    【解决方案1】:

    我使用了以下内容:

    ...............
    UrlGeneratorInterface::ABSOLUTE_URL
            );
            $token = $user->getToken();
            $creation = new \DateTime("now");
            $valid = (new \DateTime("now"))->modify('+1 day');
            $token->setToken($pledge);
            $token->setCreation($creation);
            $token->setValid($valid);
            $token->setActive(true);
            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($token);
            $entityManager->flush();
    ................
    

    它按我的预期工作,这是正确的方法吗?

    【讨论】:

    • 我想这取决于你需要什么。据我所知,我猜你想在User 要求恢复密码时给User 一个生成的Token,然后通过电子邮件将包含Token 值的链接发送到User。您(计划)使用Token$active 属性检查是否仍允许使用它来更改User 的密码。是这样吗?
    【解决方案2】:

    我会建议一些更改:

    • 每次都生成一个全新的实体,而不是编辑现有的Token。请记住将orphan removal 设置为删除旧的Token(如果存在)

    • 坚持$user,而不是$token。牢记owning side

    • Token 实体本身中,不需要保留$active 字段,因为实体本身似乎在$valid 下有一个到期日期。我会将该名称更改为$validUntil 左右(因此它表示日期/时间)并使用它来检查Token 是否确实仍然处于活动状态。您可以像这样修改Token 实体:

    private $validUntil;
    
    public function isActive()
    {
        return $this->validUntil > (new DateTime('now'));
    }
    
    • 我不会验证if ($form->isSubmitted() && $form->isValid()) 中的电子邮件,而是添加一个custom validation constraint 来检查带有给定电子邮件的User 是否存在。这样,如果没有User,您永远不会通过$form->isValid() 部分,并且email 字段上的错误会自动附加到它,因此不需要闪烁消息(除非你想要它)

    在更广泛的情况下,我还将Token 实体更改为具有用于关系的$user 属性(而不是$username),以及用于Token 值的$value 属性(而不是$token)。我也会在Profile 实体中将$username 重命名为$user(也可能在与User 相关的其他实体中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-09
      • 2021-10-18
      • 1970-01-01
      • 2021-05-16
      • 2019-06-04
      • 1970-01-01
      相关资源
      最近更新 更多