简体   繁体   中英

How to compare two doctrine objects?

Using symfony 3.4 (php). How do I compare two objects whether they are the same?

My usecase is as follows: I get the logged in user via

$user = $this->get('security.token_storage')->getToken()->getUser();

and I have a user id given in the url that is provided via the function call

public function showUserAction(Request $request, Member $userToDisplay) { ...

Now I want to check whether these two user objects are the same - in this case I would redirect to the page which shows the profile of the logged in user.

Can I simply do

if ($user === $userToDisplay) { ... }

? How is comparison done in this case? What I really want is doing something like

if ($user->getId() === $userToDisplay->getId()) { ... }

, but I really like the first solution because of its simplicity - and it actually works. But is that just a coincidence, or is this actually how doctrine is supposed to be used?

I know from Java that I would implement the equals() and hashCode() -methods - is there something similar in PHP?

In my two example above, is there a difference between using == and === ?

The cleanest way in my opinion would be to use the ->getId() comparison. It is easy to read even from novices that do not have to wonder how php handles object equality (== means same properties and class, === means same instance references), or wonder if symfony/doctrine might return the same instance in the token manager and in the doctrine query.

http://php.net/manual/en/language.oop5.object-comparison.php

I cannot comment on if doctrine / symfony might return the same instance on both object references. I do not know. And honestly noone probably can predict it with certainty (especially if you factor in things like caching), unless they have very intricate knowledge about doctrine/symfony source code.

Oh and keep in mind that

$this->get('security.token_storage')->getToken()->getUser()

does not always return a user object. For example it can return text if the user is not logged in.

So I would also add a check inside the if (before the id comparison) to check if $user is indeed an actual Member object. Otherwise you can get an exception when you try to access the getId() method

$user instanceof Member

By the way, if you want to handle such stuff in the proper Symfony way, keep your controller lean and clean and nicely separate your code, you should create and register a Voter and use something like

if($this->isGranted('view', $profile)){...}

The rest of the Voter code is rather too much to quote here, but even if the guide link below breaks you should be able to easily find info on voters by googling it.

TLDR is that you specify access voters as tagged services (for example ProfileVoter). Those voters get an action (for example view) and a subject instance (for example $profile) as parameters, and then use their internal code to decide if the token user has the right to perform the action on the subject instance (return $user instanceof Member && $user->getId() === $profile->getUser()->getId()).

https://symfony.com/doc/3.4/security/voters.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM