Symfony 5:在null上调用成员函数encodePassword

问题描述

嗨,我正在尝试为我的应用程序用户编码我的密码,所以我试图在我的setPassword函数中进行加密
不幸的是,我收到了一个我不明白的错误:在空error pic

调用成员函数encodePassword()
  <?PHP

 namespace App\Entity;
 use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
 use Gedmo\Mapping\Annotation as Gedmo;
 use Vich\UploaderBundle\Mapping\Annotation as Vich;
 use Symfony\Component\HttpFoundation\File\File;
 use Doctrine\ORM\Mapping as ORM;
 use Symfony\Component\Security\Core\User\UserInterface;

/**
 * Admin
 *@Vich\Uploadable
 * @ORM\Table(name="admin")
 * @ORM\Entity
 */
 class Admin implements UserInterface 
 {
  /**
 * @var int
 *
 * @ORM\Column(name="id",type="integer",nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * Undocumented variable
 *
 * @var UserPasswordEncoderInterface
 */
 private $passwordEncoder ;

    /**
 * @see UserInterface
 */
public function getpassword(): string
{
    return (string) $this->password;
}

public function setPassword(string $password): self

    {
     $hash= $this->passwordEncoder->encodePassword($this,$password);
     $this->password=$hash;
     return $this ;
    }
     ....... 

出什么问题了,我该如何解决! thnx

解决方法

我试图添加事件监听器,所以我创建了此类

  <?php
  namespace App\Controller\Admin;
  use App\Entity\Admin;
  use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  use EasyCorp\Bundle\EasyAdminBundle\EventListener\AdminContextListener;

 class AdminController extends AdminContextListener
 {
 /**
 * @var UserPasswordEncoderInterface
 */
 private $encoder ;
 public function __construct(UserPasswordEncoderInterface $encoder)
 {
   $this->encoder=$encoder;
  }
 public static function getSetPasswordEvent()
 {
    return [
        BeforeEntityPersistedEvent::class => ['setPassword'],];
}
public function setPassword(BeforeEntityPersistedEvent $event)
{
    $entity = $event->getEntityInstance();
    if (!($entity instanceof Admin)) {
        return;
    }
    $encoded = $this->encoder->encodePassword($entity,$entity->getPassword());
    $entity->setPassword($encoded);
   }
  }

它也不起作用

,

但这是可行的

<?php
namespace App\Controller\Admin;

use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
use EasyCorp\Bundle\EasyAdminBundle\Field\Field;
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class UserCrudController extends AbstractCrudController
{
    /** @var UserPasswordEncoderInterface */
    private $passwordEncoder;

    public static function getEntityFqcn(): string
    {
        return User::class;
    }

    public function configureFields(string $pageName): iterable
    {
        return [
            FormField::addPanel('Change password')->setIcon('fa fa-key'),Field::new('plainPassword','New password')->onlyOnForms()
                ->setFormType(RepeatedType::class)
                ->setFormTypeOptions([
                    'type' => PasswordType::class,'first_options' => ['label' => 'New password'],'second_options' => ['label' => 'Repeat password'],]),];
    }

    public function createEditFormBuilder(EntityDto $entityDto,KeyValueStore $formOptions,AdminContext $context): FormBuilderInterface
    {
        $formBuilder = parent::createEditFormBuilder($entityDto,$formOptions,$context);

        $this->addEncodePasswordEventListener($formBuilder);

        return $formBuilder;
    }

    public function createNewFormBuilder(EntityDto $entityDto,AdminContext $context): FormBuilderInterface
    {
        $formBuilder = parent::createNewFormBuilder($entityDto,$context);

        $this->addEncodePasswordEventListener($formBuilder);

        return $formBuilder;
    }

    /**
     * @required
     */
    public function setEncoder(UserPasswordEncoderInterface $passwordEncoder): void
    {
        $this->passwordEncoder = $passwordEncoder;
    }

    protected function addEncodePasswordEventListener(FormBuilderInterface $formBuilder)
    {
        $formBuilder->addEventListener(FormEvents::SUBMIT,function (FormEvent $event) {
            /** @var User $user */
            $user = $event->getData();
            if ($user->getPlainPassword()) {
                $user->setPassword($this->passwordEncoder->encodePassword($user,$user->getPlainPassword()));
            }
        });
    }
}
,

您应该在用户注册时执行此操作,因此请在执行flush()之前添加此代码;对于新用户:

    $user = new UserEntity();
    $user->setEmail($request->getEmail());

    if ($request->getPassword())
    {
        $createUser->setPassword($this->encoder->encodePassword($user,$request->getPassword()));
    }

    $this->entityManager->persist($createUser);
    $this->entityManager->flush();
    $this->entityManager->clear();

注意:$ request包含有效载荷来自前端{“ email”:“”,“ passwprd”:“”}。

注意:$ createUser是要刷新的用户对象。