如何比较两个教义对象?

How to compare two doctrine objects?

提问人:Mathias Bader 提问时间:6/16/2018 最后编辑:Mathias Bader 更新时间:7/10/2018 访问量:6361

问:

使用 symfony 3.4 (php)。如何比较两个对象是否相同?

我的用例如下:我通过以下方式获取登录用户

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

我在通过函数调用提供的 url 中给出了一个用户 ID

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

现在我想检查这两个用户对象是否相同 - 在这种情况下,我将重定向到显示登录用户配置文件的页面。

我可以简单地做吗

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

?在这种情况下,如何进行比较?我真正想要的是做类似的事情

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

,但我真的很喜欢第一个解决方案,因为它很简单 - 而且它确实有效。但这只是一个巧合,还是这实际上是教义应该被使用的方式?

我从 Java 中知道我会实现 和 -methods - PHP 中是否有类似的东西?equals()hashCode()

在我上面的两个例子中,使用 和 之间有区别吗?=====

php 相等 symfony-3.4

评论

0赞 u_mulder 6/16/2018
遵循手册:php.net/manual/en/language.oop5.object-comparison.php
2赞 u_mulder 6/16/2018
第二个解决方案更精确,它显示了真正应该比较的内容,我想它更快。我会用它。

答:

4赞 Dimitris 7/10/2018 #1

在我看来,最干净的方法是使用 ->getId() 比较。 即使对于不必想知道 php 如何处理对象相等的新手来说,也很容易阅读(== 表示相同的属性和类,=== 表示相同的实例引用),或者想知道 symfony/doctrine 是否会在令牌管理器和 doctrine 查询中返回相同的实例。

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

我无法评论doctrine / symfony是否会在两个对象引用上返回相同的实例。我不知道。老实说,没有人能肯定地预测它(特别是如果你考虑到缓存之类的东西),除非他们对教义/symfony源代码有非常复杂的知识。

哦,请记住

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

并不总是返回用户对象。例如,如果用户未登录,它可以返回文本。

因此,我还将在 if(在 id 比较之前)中添加一个检查$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