Как сравнить два объекта доктрины?

Использование Symfony 3.4 (php). Как сравнить два объекта, одинаковы ли они?

Мой вариант использования выглядит следующим образом: я получаю зарегистрированного пользователя через

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

и у меня есть идентификатор пользователя, указанный в URL-адресе, который предоставляется через вызов функции

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

Теперь я хочу проверить, являются ли эти два пользовательских объекта одинаковыми - в этом случае я бы перенаправил на страницу, которая показывает профиль вошедшего в систему пользователя.

Могу ли я просто сделать

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

? Как происходит сравнение в этом случае? Я действительно хочу сделать что-то вроде

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

, но первое решение мне очень нравится из-за его простоты — и оно действительно работает. Но является ли это простым совпадением или действительно так должно использоваться учение?

Я знаю из Java, что я бы реализовал equals() и hashCode()-методы - есть ли что-то подобное в PHP?

В моих двух примерах выше, есть ли разница между использованием ==и ===?


person Mathias Bader    schedule 16.06.2018    source источник
comment
Следуйте руководству: php.net/manual/en/language.oop5. объект-comparison.php   -  person u_mulder    schedule 16.06.2018
comment
А второе решение более точное, оно показывает, что действительно нужно сравнивать, и я полагаю, что оно быстрее. Я бы использовал это.   -  person u_mulder    schedule 16.06.2018


Ответы (1)


На мой взгляд, самым чистым способом было бы использовать сравнение ->getId(). Его легко читать даже новичкам, которым не нужно задаваться вопросом, как php обрабатывает равенство объектов (== означает те же свойства и класс, === означает те же ссылки на экземпляры) или задаваться вопросом, может ли symfony/doctrine вернуть один и тот же экземпляр в диспетчер токенов и в запросе доктрины.

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

Я не могу комментировать, может ли доктрина / symfony возвращать один и тот же экземпляр для обеих ссылок на объекты. Я не знаю. И, честно говоря, никто, вероятно, не может предсказать это с уверенностью (особенно если учесть такие вещи, как кэширование), если только они не обладают очень сложными знаниями об исходном коде доктрины/symfony.

О, и имейте в виду, что

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

не всегда возвращает пользовательский объект. Например, он может возвращать текст, если пользователь не вошел в систему.

Поэтому я бы также добавил проверку внутри if (перед сравнением идентификаторов), чтобы проверить, действительно ли $user является фактическим объектом Member. В противном случае вы можете получить исключение при попытке доступа к методу getId().

$user instanceof Member

Между прочим, если вы хотите обрабатывать такие вещи надлежащим образом Symfony, содержать ваш контроллер в чистоте и чистоте, а также красиво отделять свой код, вы должны создать и зарегистрировать Voter и использовать что-то вроде

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

Остальную часть кода избирателя слишком много, чтобы цитировать ее здесь, но даже если приведенная ниже ссылка на руководство не работает, вы сможете легко найти информацию о избирателях, погуглив ее.

TLDR заключается в том, что вы указываете избирателей доступа как сервисы с тегами (например, ProfileVoter). Эти избиратели получают действие (например, просмотр) и экземпляр субъекта (например, $profile) в качестве параметров, а затем используют свой внутренний код, чтобы решить, имеет ли пользователь токена право выполнять действие над экземпляром субъекта (возврат $user instanceof Member && $user->getId() === $profile->getUser()->getId()).

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

person Dimitris    schedule 10.07.2018