使用学说时要考虑到这一点
#php #symfony #doctrine

我想与您分享一个常见错误,在使用学说时可能会发生,这可能是一场噩梦,直到​​您注意到为什么会发生。

让我们使用一个示例来看看它。想象我们正在与这些实体合作:

#[ORM\Entity(repositoryClass: UserRepository::class)]
class User {

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 150)]
    private string $name;

    #[ORM\Column(length: 255)]
    private string $pass;

    #[ORM\Column(length: 100)]
    private string $email;

    // getters & setters
}

#[ORM\Entity(repositoryClass: UserAddressRepository::class)]
class UserAddress {

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne]
    private User $user;

    #[ORM\Column(length: 150)]
    private string $address;

    // getters & setters
}

现在,当您收到新登记册的请求时,您会做类似的事情:

$user = new User();
$user->setName('Peter');
$user->setPass('xxxxx');
$user->setEmail('peter.morris@gmail.com');

$address = new UserAddress();
$address->setUser($user);
$address->setAddress('Down street 25B');

$em->persist($user);
$em->persist($address);
$em->flush();

$eventDispatcher->dispatch(new UserRegisteredEvent($user));

到目前为止,此代码似乎正确。它创建一个用户和一个地址,将它们保留在数据库中,并分发和事件。现在让我们看看订户:


class UserSubscriber implements EventSubscriberInterface {

    public static function getSubscribedEvents(): array
    {
        return [
            UserRegisteredEvent::class => 'onUserRegistered'
        ];
    }

    public function onUserRegistered(UserRegisteredEvent $e){
       $user = $e->getUser();
       $address = $user->getAddress();
       $addrName = $address->getAddress();
    }
}

执行行 $ addrname = $ address-> getAddress()您将获得以下错误:

  Call to a member function getAddress() on null  

这是因为我们一直坚持两个实体,但是我们尚未刷新用户实体。

为了避免这种错误,我们可以按照下一步(当然还有其他步骤):

刷新用户对象在将其传递给活动之前

$em->persist($user);
$em->persist($address);
$em->flush();

$em->refresh($user);

$eventDispatcher->dispatch(new UserRegisteredEvent($user))

这使我们可以在使用订户之前重新填充用户。

将用户标识符传递给活动

$em->persist($user);
$em->persist($address);
$em->flush();

$eventDispatcher->dispatch(new UserRegisteredEvent($user->getId()));

// -------------------------------------------------------

public function onUserRegistered(UserRegisteredEvent $e){

    $user = $em->getRepository(User::class)->find($e->getId());

    $user = $e->getUser();
    $address = $user->getAddress();
    $addrName = $address->getAddress();
}

这样,将用户标识符传递给事件,因此从数据库中获得了新的用户

是订户

结论

这似乎是一个非常简单的错误,但是当您有一个项目生产工作并且开始遇到此类错误时,这可能是一场噩梦,而您的代码在语法上是正确的,但在语义上不正确。